String Reading Issues

This is a discussion on String Reading Issues within the C Programming forums, part of the General Programming Boards category; I'm working on an assignment that takes some inputs for an address book. However, I have problems getting the input ...

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    21

    String Reading Issues

    I'm working on an assignment that takes some inputs for an address book. However, I have problems getting the input to read properly. Here's the section so far:
    Code:
    char addcontact ()
    {
            auto char input1[100], input2[100], input3[100], input4[6], input5[10];
            char c;
            int cnt = 0;
            fflush (stdin);
            printf("First Name: ");
            fgets(input1, 100, stdin);
            strcpy (InfoList[listcnt].firstname, input1);
    
            printf("Last Name: ");
            fgets(input2, 100, stdin);
            strncpy (InfoList[listcnt].lastname, input2, cnt);
    
            printf("Address: ");
            while ((c = getchar()) != '\n')
            fgets(input3, 100, stdin);
            strncpy (InfoList[listcnt].address, input3, cnt);
    
            printf("Postal Code: ");
            fgets(input4, 7, stdin);
            strcpy (InfoList[listcnt].pcode, input4);
    
            printf("Phone Number: ");
            fgets(input5, 11, stdin);
            strcpy (InfoList[listcnt].phone, input5);
    
            listcnt++;
            menu();
    }
    The input:
    Code:
    First Name: John
    Last Name: Doe
    Address: 123 Street
    
    Postal Code: A1B 2C3
    Phone Number:
    And the output:
    Code:
    Contact 1
    First Name: John
    
    Last Name:
    Address:
    Postal Code: A1B- 2C
    Phone Number: (3
    ) -
    I have to press return twice to get past the address section, and it won't even let me enter a phone number. After that, it ignores the address and for some reason overflows the postal code into the phone number. Any idea what's wrong here?

  2. #2
    ZuK
    ZuK is offline
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
            while ((c = getchar()) != '\n')
                fgets(input3, 100, stdin);
    That doesn't make sense to me, unless you want to wait for a '\n' from the keyboard.
    but then it would have to be
    Code:
            while ((c = getchar()) != '\n');
    Code:
    strncpy (InfoList[listcnt].lastname, input2, cnt);
    You have initialized cnt to 0 -> nothing will be copied.

    Kurt
    Last edited by ZuK; 11-18-2007 at 10:28 AM.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,420
    You're also using fflush(stdin), which makes no sense at all.
    See the FAQ.

    If you're using fgets(), then don't use any scanf() calls, as this will surely mess you up.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    21
    Quote Originally Posted by ZuK View Post
    Code:
            while ((c = getchar()) != '\n')
                fgets(input3, 100, stdin);
    That doesn't make sense to me, unless you want to wait for a '\n' from the keyboard.
    but then it would have to be
    Code:
            while ((c = getchar()) != '\n');
    Code:
    strncpy (InfoList[listcnt].lastname, input2, cnt);
    You have initialized cnt to 0 -> nothing will be copied.

    Kurt
    Gah, sorry, those are all stupid proofreading mistakes, stuff I forgot to nuke from prior fixing attempts.

    Salem, I couldn't find anything in the FAQs about fflush-what should I be using?

    Anyways, here's what I've got now:
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct InfoStruct
    {
            char firstname[40];
            char lastname[40];
            char address[100];
            char pcode[6];
            char phone[10];
    }InfoList[10];
    
    int listcnt = 0;
    
    int menu ();
    char addcontact();
    char displaycontacts();
    
    int main ()
    {
            menu();
    }
    
    int menu()
    {
            int choice;
            char c[1];
    
            printf("1: Add New Contact\n");
            printf("2: Display Current Contacts\n");
            printf("3: Search for a contact\n");
            printf("4: Save to a file\n");
            printf("5: Load contacts from file\n");
            printf("6: Exit\n");
            printf("Enter a choice: ");
            fgets(c, 1, stdin);
            choice = atoi(c);
    
            switch(choice)
      {
                    case 1:
                            addcontact();
                    break;
    
                    case 2:
                            displaycontacts();
                    break;
    
                    case 3:
                            printf("Search for a contact\n");
                    break;
    
                    case 4:
                            printf("Save to a file\n");
                    break;
    
                    case 5:
                            printf("Load contacts from file\n");
                    break;
                    
                   case 6:
    
                    break;
    
                    default:
                            printf("Please enter a valid selection\n");
            }
    
    }
    
    char addcontact ()
    {
            auto char input1[100], input2[100], input3[100], input4[6], input5[10];
            char c;
            int cnt = 0;
            fflush (stdin);
            printf("First Name: ");
            fgets(input1, 100, stdin);
            strcpy (InfoList[listcnt].firstname, input1);
    
            printf("Last Name: ");
            fgets(input2, 100, stdin);
            strcpy (InfoList[listcnt].lastname, input2);
    
            printf("Address: ");
            fgets(input3, 100, stdin);
            strcpy (InfoList[listcnt].address, input3);
    
            printf("Postal Code: ");
            fgets(input4, 7, stdin);
            strcpy (InfoList[listcnt].pcode, input4);
    
            printf("Phone Number: ");
            fgets(input5, 11, stdin);
            strcpy (InfoList[listcnt].phone, input5);
    
            listcnt++;
            menu();
    }
    The problem now is that I can't even take an input for the menu, and I still can't put anything into the Phone entry.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, fflush(stdin) is "undefined" - fflush is guaranteed only for output [where forces any buffered data to be actually output to the file itself].

    Code:
    while ((c = getchar()) != '\n');
    will remove any input in the buffer - however, to "start" with that means that if the user hasn't got a newline already typed in, the user will have to type it in. It is probably better if you change your code in your menu - more on that below.

    Code:
            char c[1];
            ....
            printf("Enter a choice: ");
            fgets(c, 1, stdin);
            choice = atoi(c);
    I doubt this ever works. c is an array of a single character. reading in one character with fgets() will get you "an empty string", because that's the only string that fits in one character [c[0] = '\0' and nothing else - because there are no further elements in the array to hold anything else]. You need to make it a char-array of at least 2 to be able to read anything sensible in. If you make it another character, it will also read in the newline after the user's choice. If you want to know if there was any other "rubbish" typed in, you can check the second character like this:
    Code:
       if (c[1] != '\n') ...  // more than one digit/letter entered - perhaps you should read away anything else in the input buffer with the code suggested above.
    Finally, atoi() is extremely bad at handling error conditions - such as "no numbers" or "more numbers than can fit into an integer" [not a problem if you only read one or two digits, but it's worth bearing in mind if you ever feel tempted to use it elsewhere].

    The solution to the "atoi drawbacks" is to use "strtol()", which is much more wellbehaved in a stressed situation.

    I hope this helps.

    --
    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.

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    21
    Well, the fflush seems to be working for what I need it to do, and that's to get rid of the newline read in from the menu.

    However, I still can't get it to read in the last section. Here's what happens when I run:
    Code:
    1: Add New Contact
    2: Display Current Contacts
    3: Search for a contact
    4: Save to a file
    5: Load contacts from file
    6: Exit
    Enter a choice: 1
    First Name: John
    Last Name: Doe
    Address: 123 X Street
    Postal Code: A1B2C3
    Phone Number: 1: Add New Contact
    2: Display Current Contacts
    3: Search for a contact
    4: Save to a file
    5: Load contacts from file
    6: Exit
    Enter a choice: 6

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,682
    use this function instead of fflush. This does the same job. Call then before the fgets.

    Code:
    void clear_buffer(void)
    {
         int ch;
         
         while((ch = getchar()) != '\n' && ch != EOF);
    }
    ssharish

  8. #8
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,420
    > fgets(c, 1, stdin);
    This is useless.
    To store any input from the user, you need at least TWO chars (one for a user input character, and another for a \0).
    If you passed a decent sized array, then the whole need for fflush(stdin) GOES AWAY.

    Besides, if your argument for using it is "it seems to work", then that doesn't help your case.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    21
    That's not there anymore, it's been changed to actually work.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Replies: 7
    Last Post: 02-02-2009, 06:27 AM
  3. clearing buffer after reading string w/ scanf()
    By fisheromen1031 in forum C Programming
    Replies: 11
    Last Post: 08-01-2005, 09:33 AM
  4. ........ed off at functions
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-29-2002, 09:37 PM
  5. string handling
    By lessrain in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 07:36 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21