Thread: Char array display error...

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    For standard integer types, i++ and ++i are identical [1].

    In C++, where you can use ++ on "complex" data types, there is a slight difference in efficiency between x++ and ++x (giving the latter a small advantage), which means that some people use ++x. The main reason for this is that x++ require that you FIRST make a copy of the value, then increment it. The object itself doesn't have to be very big before this overhead of copying the object becomes noticable.

    [1] Of course, this only applies if the x++ or ++x is "standalone" - if it's used inside an array index, or some such, there is of course a difference in that the ++x will FIRST increment the value, then be used as an index, whilst x++ will first be used as an index, THEN update the value.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #17
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Karpaty View Post
    I even found a little misplaced assignment in the above code (yes, i realize you did not test the code prior posting it). I just thought i point it out for those who might find this code useful in the future. You assigned "0" to "sum" inside the FOR loop, so every time the loops repeats itself it overwrites the value of "sum" to "0".
    In my "version" I moved the assignment statement just above the FOR loop line... Seems to produce the desired result
    Yep, good catch. I'll leave that in there for now, don't feel like changing it.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #18
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    I've been trying to modify the code to be able to add a description to each item by adding a new string array called "description" and modifying the code a bit. However, its not as easy as I originally thought. Go figures... hehe

    Note: the new code is in red

    The first red line is the declaration of the string array for description.
    The third red line asks the user to enter the description for items 1-8
    This follows with the "gets" statement to get the value of the description. I used gets instead of "scanf" because the description might have spaces in there and "scanf" doesnt do spaces.
    On the same line I also have [choice-1] - the reason for this is because I want to match the name and its description...
    However, the problem is, that the gets() statement doesnt do what it supposed to do... The program skips it. I mean it does display "Description", but doesnt give me the chance to enter the description and goes straight to "Price"...
    What am i doing wrong?

    Code:
    #include <stdio.h>
    #define MENU 11
    #define ITEMS 8
    
    int main ( ) {
    
    char item[MENU][20] = {" Bread", " Butt.", " Conf.",
    		" Fruit", " Meat", " Milk", " Veg.",
    		" Other", " Sub-total", "Total", "Quit"};
    char description[ITEMS][20];
    int i;
    int choice;
    float cost;
    float sum, tendered, change;
    float subtotals[ITEMS] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
    
    while (choice != 11)
      {
        printf("\n Enter your choice:\n");
        for (i = 0; i < MENU; i++)
        {
            printf("\t&#37;d. %s\n", (i + 1), item[i]);
        }
        printf("\t\t--> ");
        scanf("%d", &choice);
        getchar();
    
        if(choice > 0 && choice < 9)
        {
            printf(" Description:\t\t");
            gets(description[choice-1]);
            printf(" Price:\t\t");
            scanf("%f", &cost);
            subtotals[choice-1] += cost;
        }
        else if(choice == 9)
        {
            sum = 0;
            for(i = 0; i < ITEMS; i++)
            {
                if(subtotals[i] > 0)
                {
                    printf("\n%s: %s\t\t\t%9.2f", item[i], description[i], subtotals[i]);
                    sum += subtotals[i];
                }
            }
            printf("\n----------------------------------\n");
            printf(" Total:\t\t\t%9.2f\n", sum);
            printf("----------------------------------\n");
        }
        else if(choice == 10)
        {
            sum = 0;
            for(i = 0; i < ITEMS; i++)
            {
                if(subtotals[i] > 0 )
                {
                    printf("\n%s: %s\t\t\t%9.2f", item[i], description[i], subtotals[i]);
                    sum += subtotals[i];
                }
            }
            printf("\n----------------------------------\n");
            printf(" Total:\t\t\t%9.2f\n", sum);
            printf("----------------------------------\n");
            printf(" Tendered:\t\t   ");
            scanf("%f", &tendered);
            change = tendered - sum;
            printf(" Change:\t\t%9.2f\n", change);
        }
      }
    }
    Last edited by Karpaty; 10-30-2007 at 08:06 PM.

  4. #19
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Don't use gets, use fgets instead. The previous scanf call is likely leaving the newline character in the input stream which may be read (is read) by later input operations, i.e. gets/fgets. gets sees this and thinks you tried to type something in followed by the newline/enter key. I think there is a FAQ entry on this.

    Also, the way things work, you can loop through and enter in the same groups of food multiple times, you could pick Meat then Bread then Meat again for example, and each time doing that you'd be forced to enter a description that would overwrite the previous description entered. Is that what you want to do? And, when printing out the totals/subtotals, depending on the descriptions entered and their lengths, your formating of the prices may be off unless you do something about it.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #20
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Quote Originally Posted by hk_mp5kpdw View Post
    Don't use gets, use fgets instead. The previous scanf call is likely leaving the newline character in the input stream...
    I think I can fix this problem by including the...

    Code:
    	getchar();
    ...line after the previous scanf() statement (see the edited code in the previous post)...

    Quote Originally Posted by hk_mp5kpdw View Post
    Also, the way things work, you can loop through and enter in the same groups of food multiple times, you could pick Meat then Bread then Meat again for example, and each time doing that you'd be forced to enter a description that would overwrite the previous description entered. Is that what you want to do? And, when printing out the totals/subtotals, depending on the descriptions entered and their lengths, your formating of the prices may be off unless you do something about it.
    Hmm, when you put it this way, it seems much harder than I thought. No, I do not want to overwrite any entry. I was thinking of grouping each entry for, lets say, bread and butter (and the rest), so you could have something like:
    Code:
    Bread:
      Whole bread white:	$1.50
      Whole bread brown:	$1.65
    Butter:
      Type 1 butter:	$2.00
      Type 2 butter:	$2.15
    ------------------------------------------
    TOTAL:			$7.30
    Hmm, i think my whole program would have to be completely rewritten...
    I dont know whether im tired from coding all day, or just luck of knowledge (or both), but I, honestly, dont even know where to start...
    Last edited by Karpaty; 10-30-2007 at 08:01 PM.

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, at the level that the rest of the code is, it is non-trivial to solve that.

    The most obvious and simple solution is a three-dimensional array and a further variable to track the number of items per category that you've got so far [so you know how many items of bread has been purchased, for example].

    The three-dimension array is a fine solution aside from using rather a lot of memory [because you get 8 * nitems * 20, or 160 * the number of items per category amount of memory - not a huge amount for a modern PC as long as you keep the number of items per category sort of sane - but if you want to keep up with a weekly shop for a family of 2 adults and three teenagers, you may end up with rather a large amount of types of bread, veg, fruit, etc].

    The alternative is that you dynamically allocate memory for each category - for example using a linked list per category. But this is probably beyond the scope of your current level of knowledge/understanding.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Actually we did do the dynamic allocation of memory (malloc, calloc etc) last week, but we were told it was not essential for this particular assignment.
    Im gonna try to do it anyway, since it seems 3-dimensional array is a bit too complicated for me at this stage...
    I tried to write a simple program to see how this whole idea of 3D array would work, but unfortunatelly with not much luck...

    Code:
    #include <stdio.h>
    #define ITEMS 8
    #define DESCRIPTION 20
    #define CHARACTERS 20
    
    int main ( )
    {
        char item[ITEMS][DESCRIPTION][CHARACTERS];
        int i, j;
    
        for (i = 0; i < ITEMS; i++)
        {
            printf("Enter the name of the item: ");
            gets(item[i]);
            for (j = 0; j < DESCRIPTION; j++)
            {
                printf("Enter the description: ");
                gets(item[i][j]);
            }
        }
    
        printf("ITEMS:\t\tDESCRIPTION:\n");
        for (i = 0; i < ITEMS; i++)
        {
            for (j = 0; j < DESCRIPTION; j++)
            {
                printf("&#37;s\t\t%s\n", item[i], item[i][j]);
            }
        }
    }
    Even without compiling I somehow knew there would be some problems with the red parts of the code, but after searching for a solutions for almost an hour, i gave up... Cant believe there are so few C programming 3D array examples out there...

    Im gonna start working on "dynamic allocation" solution now and see how it goes...
    Last edited by Karpaty; 10-31-2007 at 07:03 AM.

  8. #23
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    First of all, don't use gets(), use fgets(), as the latter is safe, the former isn't.

    [If your teacher says "use gets" you probably should consider also replacing the teacher with a safer one... ]

    Your code looks mainly correct, but the red section is broken because you are using a gets() to read into a 2D array - which is definitely not impossible, just wrong!

    The correct solution is two have a different array with the group description, e.g:
    Code:
        char item[ITEMS][DESCRIPTION][CHARACTERS];
        char descr[ITEMS][CHARACTERS]; 
        int i, j;
    
        for (i = 0; i < ITEMS; i++)
        {
            printf("Enter the name of the item: ");
            gets(descr[i]);
            for (j = 0; j < DESCRIPTION; j++)
            {
                printf("Enter the description: ");
                gets(item[i][j]);
            }
        }
    I think you are capable of figuring how to print the same.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #24
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Quote Originally Posted by matsp View Post
    [If your teacher says "use gets" you probably should consider also replacing the teacher with a safer one... ]
    Hehe, you noticed that didnt you? Yeah, we only did gets() at this point, so I was quite reluctant to jump ahead of myself, even though everyone around said fgets() is better.
    Thank you as always... Will work on that...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Quantum Random Bit Generator
    By shawnt in forum C++ Programming
    Replies: 62
    Last Post: 06-18-2008, 10:17 AM
  3. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  4. load gif into program
    By willc0de4food in forum Windows Programming
    Replies: 14
    Last Post: 01-11-2006, 10:43 AM
  5. C++ compilation issues
    By Rupan in forum C++ Programming
    Replies: 1
    Last Post: 08-22-2005, 05:45 AM