Thread: Problem with array of structures

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    21

    Problem with array of structures

    Hey guys. Please have a look at this code. I'm not gettin the expected output... Please help.

    Code:
    #include<stdio.h>
    #include<math.h>
    #include<conio.h>
    void main()
    {
    	struct book
    	{
    		char name;
    		float price;
    		int pages;
    	};
    	struct book b[2];
    	int i;
    	for(i=0;i<2;i++)
    	{
    		printf("\nEnter name, price and pages");
    		scanf("%c %f %d", &b[i].name, &b[i].price, &b[i].pages");
    	}
    	for(i=0;i<2;i++)
    		printf("%c %f %d", b[i].name, b[i].price, b[i].pages");
    	getch();
    }
    
    ///// This section is included to avoid Linker Error
    
    linkfloat()
    {
    	float a=0, *b;
    	b=&a;
    	a=*b;
    }
    
    
    /// This section is included to avoid Linker Error
    Input given is(for eg)

    s 456 234

    d 456 889

    output

    s 456.00000 234

    garbage value

  2. #2
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    The problem is that the newline character that terminates your first input remains in the input stream (since it can't be used as part of the int stored in pages), and then it messes up the next line of input: the newline character itself is accepted as the "name" for the second entry, and then the "d" that you entered can't be matched to a float for "price" so scanf returns prematurely without reading anything for "price" and "pages" of the second struct.

    You can solve this by adding a call to getchar() to extract (and ignore) that newline character, e.g.:
    Code:
    //...
            printf("\nEnter name, price and pages");
            scanf("%c %f %d", &b[i].name, &b[i].price, &b[i].pages);
            getchar();
    //...
    PS: I don't understand the point of your linkfloat function "to avoid linker error". What linker error? And how does that code avoid it?

  3. #3
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    Code:
    int main(void)
    {
    	struct book
    	{
    		char name;
    		float price;
    		int pages;
    	};
    
    	struct book b[2];
    	int i;
    
    	for(i=0;i<2;i++)
    	{
    		printf("\nEnter name, price and pages:\t");
    		scanf("%c %f %d", &(b[i].name), &(b[i].price), &(b[i].pages) "); //Extra quotes ?
                    //Flush \n
    	}
    
    	for(i=0;i<2;i++)
    		printf("%c %f %d", b[i].name, b[i].price, b[i].pages "); //Extra quotes
    	getch();
    
     return 0;
    }
    1) Main should be int main(void)
    2) Return int at the end
    3) There are extra quotes at both scanf and printf
    4) Use parenthesis to be sure about where you want to store a variable whenever & or * used.
    5) Scanf reads a char/float/int but also and the newline character \n. The last one should be flushed from input stream because it's waiting on the queue for the next input. You can use a while(getchar()!='\n'); (simple way for your problem) after scanf.

    //Slow answer
    Last edited by ch4; 10-12-2010 at 12:20 AM.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Yet, another person using Turbo C++ ... What is the world coming to!

    Was there some large time machine which in 1990 transported people 20 years into the future, that arrived recently? I don't know how else to explain this sudden burst of people using a virtually prehistoric compiler.

    Look up the documentation on printf and you should find how to format floats however you want. This is of course, assuming that the anchient thing you're using is in the general ballpark of working as per modern documentation. Otherwise, perhaps you could find a 20 year old book on Turbo C++.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Novice
    Join Date
    Jul 2009
    Posts
    568
    The issue here is that scanf() leaves the newline character (\n) in the buffer. At first call (for b[0]), all is well, but on the consecutive call if fails terribly.
    The solution is to clean out any newlines that might be left in the buffer, like so.
    Code:
    int ch;
    for(i=0;i<2;i++)
    {
        printf("\nEnter name, price and pages");
        scanf("%c %f %d", &b[i].name, &b[i].price, &b[i].pages);
        while( ( ch = getchar() ) != EOF && ch != '\n');
    }

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Code:
    scanf("%c %f %d", &b[i].name, &b[i].price, &b[i].pages");
    The problem is in red, above. Scanf() leaves a newline char behind in the input stream, always. That is no problem for numbers, because numbers are bigger, so scanf() just goes on past the little char of the newline.

    But then you have the second time through the loop, and scanf() reaches the newline left behind from the last pages entry, and says "OK, you wanted a char. I got a char!", and accepts the newline char, as the b[1].name.

    Now things go to hell in a handbasket, since you're entering a letter for name, and now scanf() is already looking for a price. So you're now trying to feed scanf() a newline, and a char, for a price, and it's just not computing.

    So do it like this:
    Code:
    	for(i=0;i<2;i++)
    	{
    		printf("\nEnter name, price and pages");
    		scanf("%c %f %d", &b[i].name, &b[i].price, &b[i].pages");
                    getchar();  //pull off the newline char
    	}
    This is the most common noob problem, with C, imo.

    Holy Cow, I've been ninja-posted!!
    Last edited by Adak; 10-12-2010 at 12:31 AM.

  7. #7
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by R.Stiltskin
    [...]scanf returns prematurely without reading anything for "price" and "pages" of the second struct.
    So scanf() returns as soon as it can't match?

    I was somewhat under the impression that it just kept on matching to the best of its (dis)ability.

  8. #8
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by Adak
    Holy Cow, I've been ninja-posted!!
    You and me both. I was like, "Hey this thread has no answers! Maybe I can contribute something meaningful!"

    *fiddles with code*

    *posts*

    "Where did all these posts come from!?"

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Although it's used a lot in C books for new programmers, scanf() is:

    1) flakey - yes, it quits!

    2) it has a lot of cryptic specifiers.

    So yes, it works, but you REALLY have to know C to use it well, AND using it for user input is not a good idea, generally. Dumb user's have so many smart ways to break input for a program!

    @msh: Xactly!!

  10. #10
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by iMalc View Post
    Yet, another person using Turbo C++ ... What is the world coming to!

    Was there some large time machine which in 1990 transported people 20 years into the future, that arrived recently? I don't know how else to explain this sudden burst of people using a virtually prehistoric compiler.
    The End Times are nigh, surely!

    I think that it's due to the fact that there are plenty of educational institutions out there that like to keep fossilized professors with their favorite (likewise fossilized) compilers on board ("It's the one I've always thought on! There's nothing wrong with it.").

  11. #11
    Registered User
    Join Date
    Oct 2010
    Posts
    21
    hey thanks so much you guys...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 06-11-2009, 11:27 AM
  2. Problems with passing an array of structures by pointer
    By raptor1770 in forum C Programming
    Replies: 9
    Last Post: 11-29-2008, 11:01 AM
  3. Filling an Array of Structures
    By Zildjian in forum C Programming
    Replies: 5
    Last Post: 11-12-2003, 05:54 PM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM