user input problems in c

Code:
/************************************************************
 * By:		Aldis Berjoza <killasmurf86@gmail.com>
 * Date:	Sat 24 Oct 2009
 ************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOOKS 5


struct s_book {
	char	title[100];
	char	author[100];
	int	year;
	char	publishing[100];
};
typedef struct s_book t_book;


int main (void) {
	t_book *book;
	int	i,
		from,
		to;
	char tmp[5];


	if ((book = (t_book *) calloc(MAX_BOOKS, sizeof(struct s_book))) == NULL) {
		perror(NULL);
		exit(1);
	}

	printf("Input data!\n\n\n");

	for (i=0; i<MAX_BOOKS; i++) {

		printf("Author: ");
		scanf("%100s", book[i].author);
//		fgets(book[i].author, 100, stdin);
		printf("Title: ");
		scanf("%100s", book[i].title);
//		fgets(book[i].title, 100, stdin);
		printf("Publishing: ");
		scanf("%100s", book[i].publishing);
//		fgets(book[i].publishing, 100, stdin);
		printf("Year: ");
		scanf("%d", &(book[i].year));
//		fgets(tmp, 5, stdin);
//		book[i].year = atoi(tmp);
	


		printf("ok\n=========================\n\n");
	}

//	clrscr();

	printf("Search from year: ");
	scanf("%d", &from);
	printf("Search to year: ");
	scanf("%d", &to);

	printf("=================\n");
	for (i=0; i<MAX_BOOKS; i++) {
		if ((book[i].year >= from) && (book[i].year <= to)) {
			printf("%s - \"%s\", %s, %d\n",
				book[i].author,
				book[i].title,
				book[i].publishing,
				book[i].year);
		}
	}


	free(book);
	return 0;
}

I don't understand why this stupid app sometimes skip asking some fields....

What did I code wrong?
Please enlighten me.
 
I'm not using them at same time....
currently fgets is commented out

I just tried both, and get about same result....
 
No problem with input here, but changing >= to <= helps the search function:

Code:
	for (i=0; i<MAX_BOOKS; i++) {
		if ((book[i].year >= from) && (book[i].year [color="Red"]<=[/color] to))
 
The standard output is, by default, line buffered. That means output that isn't a full line (ends with '\n') might not appear immediately.

You have 2 solutions for that:

a) include a '\n' in the printf()
b) "force" the output to be displayed even incomplete.

a)
Code:
    printf("Publishing:\n");

b)
Code:
    printf("Publishing: ");
    fflush(stdout);
 
Problem was with reading integers, you should read everything as strings then convert.

fixed for ya:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOOKS 5


struct s_book {
	char	title[100];
	char	author[100];
	char	year[100];
	char	publishing[100];
};
typedef struct s_book t_book;


int main (void) {
	t_book *book;
	int	i,
		from,
		to,
		year;
	char tmp[5],
		 s_from[100],
		 s_to[100];


	if ((book = (t_book *) calloc(MAX_BOOKS, sizeof(struct s_book))) == NULL) {
		perror(NULL);
		exit(1);
	}
	
	memset(book, 0, sizeof(struct s_book) * MAX_BOOKS);

	printf("Input data!\n\n\n");

	for (i=0; i<MAX_BOOKS; i++) {

		printf("Author: ");
		scanf("%99s", book[i].author);
//		fgets(book[i].author, 100, stdin);
		printf("Title: ");
		scanf("%99s", book[i].title);
//		fgets(book[i].title, 100, stdin);
		printf("Publishing: ");
		scanf("%99s", book[i].publishing);
//		fgets(book[i].publishing, 100, stdin);
		printf("Year: ");
		scanf("%99s", book[i].year);
//		fgets(tmp, 5, stdin);
//		book[i].year = atoi(tmp);
	


		printf("ok\n=========================\n\n");
	}

//	clrscr();

	printf("Search from year: ");
	scanf("%99s", s_from);
	printf("Search to year: ");
	scanf("%99s", s_to);

	printf("=================\n");
	
	from = atoi(s_from);
	to = atoi(s_to);
	for (i=0; i<MAX_BOOKS; i++) {
		year = atoi(book[i].year );
		if ((year >= from) && (year <= to)) {
			printf("%s - \"%s\", %s, %s\n",
				book[i].author,
				book[i].title,
				book[i].publishing,
				book[i].year);
		}
	}


	free(book);
	return 0;
}
 
@ expl <<< no that didn't work...
after I press Enter it sometimes skips asking for year... it show year: then without waiting for my input it writes ok...
Code:
Author: asda dasd 
Title: Publishing: asd asd 
Year: ok
=========================

Author:

here it skipped asking for Title, and year....
It's acting like if I hit enter more than once after I tryped asda dasd for example

fflush didn't help either....
I'm really pissed about this behavior... i'm trying to figure this out for long time now.....


I bet solution is simple
 
Also, overflowing your arrays with more than 100 inputs will make it seem like the program is skipping the next field, but is actually using the overflow as new input for that field instead.
 
killasmurf86 said:
@ expl <<< no that didn't work...
after I press Enter it sometimes skips asking for year... it show year: then without waiting for my input it writes ok...
Code:
Author: asda dasd 
Title: Publishing: asd asd 
Year: ok
=========================

Author:

here it skipped asking for Title, and year....
It's acting like if I hit enter more than once after I tryped asda dasd for example

fflush didn't help either....
I'm really pissed about this behavior... i'm trying to figure this out for long time now.....


I bet solution is simple

The scanf will stop at the first space, leaving " asd" for the year.

You really should read user input with fgets() and sscanf().
 
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BOOKS 5


struct s_book {
	char	title[100];
	char	author[100];
	int		year;
	char	publishing[100];
};
typedef struct s_book t_book;


int main (void) {
	t_book *book;
	int	i,
		s_from,
		s_to;
	char tmp[7];


	if ((book = (t_book *) calloc(MAX_BOOKS, sizeof(struct s_book))) == NULL) {
		perror(NULL);
		exit(1);
	}
	
	memset(book, 0, sizeof(struct s_book) * MAX_BOOKS);

	printf("Input data!\n\n\n");

	for (i=0; i<MAX_BOOKS; i++) {

		printf("Author: ");
		fgets(book[i].author, 99, stdin);
		book[i].author[ (int) strlen(book[i].author) -1] = 0x0;

		printf("Title: ");
		fgets(book[i].title, 99, stdin);
		book[i].title[(int) strlen(book[i].title) -1] = 0x0;

		printf("Publishing: ");
		fgets(book[i].publishing, 99, stdin);
		book[i].publishing[(int) strlen(book[i].publishing) -1] = 0x0;

		printf("Year: ");
		fgets(tmp, 6, stdin);
		book[i].year = atoi(tmp);
	


		printf("ok\n=========================\n\n");
	}

//	clrscr();

	printf("Search from year: ");
	fgets(tmp, 6, stdin);
	s_from = atoi(tmp);

	printf("Search to year: ");
	fgets(tmp, 6, stdin);
	s_to = atoi(tmp);

	printf("=================\n");
	
	for (i=0; i<MAX_BOOKS; i++) {
		if ((book[i].year >= s_from) && (book[i].year <= s_to)) {
			printf("%s - \"%s\", %s, %d\n",
				book[i].author,
				book[i].title,
				book[i].publishing,
				book[i].year);
		}
	}


	free(book);
	return 0;
}

Thanks for help :D
 
killasmurf86 said:
Code:
#include <stdio.h>
        /* ... */
	char tmp[7];
        /* ... */

		printf("Year: ");
		fgets(tmp, 6, stdin);

        /* ... */

}

You can use the full size of the array in fgets(), it already takes the terminating zero into consideration.

I usually do
Code:
    char buf[100];
    fgets(buf, sizeof buf, stdin);
 
i think the problem is that you are reading from buffer without counting "\n" that will be read from the next scanf (buffered input) just change the scanf like this
Code:
		scanf("%100s%*c", book[i].author);
"%*c" tells scanf to jump one character (the newline) :)
 
Back
Top