Thread: scanf and whitespaces

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154

    scanf and whitespaces

    Hi,

    I know this is a common topic on this forum, but I haven't found a nice, clean solution anywhere. Main thing is that I'm never sure whether the solution described really applies to my code. And when I try to integrate pieces of code from those solutions in my own code it never does what I want it to .

    I request some inputs from the user:

    Code:
    puts("\n--------------------------------");
        puts("Please enter the vehicle make: ");
        scanf("%s", &vehicle_make);
        puts("Please enter the vehicle model: ");
        scanf("%s", &vehicle_model);
        puts("Please enter the model year:");
        scanf("%s", &vehicle_year);
        puts("Please enter your name:");
        scanf("%s", &tester);
        puts("--------------------------------");
    Now when I have for example a 205 GTI and enter that after Please enter the vehicle model it skips Please enter the model year. I found out that it is because of the space between 205 and GTI, because GTI is stored as vehicle_year if I enter the string above.

    Has anyone got a solution for this problem? I know it's probably quite simple, but not for me (yet) .

    Thanks very much in advance!

    René

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Yeah, don't use scanf() use fgets().

    Code:
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    
    int main()
    {
        char vehicle_make[30], vehicle_model[30], vehicle_year[30], tester[30];
        
        puts("\n--------------------------------");
        puts("Please enter the vehicle make: ");
        fgets(vehicle_make, 30, stdin);
        puts("Please enter the vehicle model: ");
        fgets(vehicle_model, 30, stdin);
        puts("Please enter the model year:");
        fgets(vehicle_year, 30, stdin);
        puts("Please enter your name:");
        fgets(tester, 30, stdin);
        puts("--------------------------------");
    }
    Last edited by SlyMaelstrom; 03-02-2006 at 10:45 AM.
    Sent from my iPad®

  3. #3
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154





    Hehe, just kidding...

    I hope it's as easy as you say but I'm off work now. I'll try this tomorrow morning first thing. Thanks!

  4. #4
    Registered User
    Join Date
    Feb 2006
    Posts
    17
    Just make sure you don't forget that, in this case, if you type less than 29 characters, fgets() will also read a \n into the buffer and this might cause you trouble if you're going to compare the string read with a constant like "quit".

  5. #5
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    Can't you also use getchar() after a scanf() to flush the buffer and avoid that error?

  6. #6
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Quote Originally Posted by richdb
    Can't you also use getchar() after a scanf() to flush the buffer and avoid that error?
    No, how would that help the fact that scanf only reads up to whitespace?
    Sent from my iPad®

  7. #7
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Quote Originally Posted by SlyMaelstrom
    Yeah, don't use scanf() use fgets().
    Yeah, fgets() works perfectly. Thanks very much for your help!

    Quote Originally Posted by tcpl
    Just make sure you don't forget that, in this case, if you type less than 29 characters, fgets() will also read a \n into the buffer and this might cause you trouble if you're going to compare the string read with a constant like "quit".
    Yeah, I noticed! Is there an easy way to fill up the fgets() string up to 29 characters? Or just simply to delete the '\n' at the end? I write this data to an exernal text file where formatting is important as well, so it would be nicer if I don't have that \n at the end.

    Thanks

    Edit: is it flushing I need to do?
    Last edited by rkooij; 03-03-2006 at 03:16 AM.

  8. #8
    Registered User
    Join Date
    Feb 2006
    Posts
    155
    Code:
    vehicle_make[strlen(vehicle_make)-1]='\0' ;
    just use this after the assignment , this clears the '\n' at the end of vehicle_make array.
    Last edited by qqqqxxxx; 03-03-2006 at 03:31 AM.

  9. #9
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Quote Originally Posted by qqqqxxxx
    Code:
    vehicle_make[strlen(vehicle_make)-1]='\0' ;
    just use this after the assignment , this clears the '\n' at the end of vehicle_make array.
    Simple and effective, what more do you want?

    Thanks a lot, appreciate your help guys!

  10. #10
    Registered User
    Join Date
    Feb 2006
    Posts
    17
    Is there an easy way to fill up the fgets() string up to 29 characters? Or just simply to delete the '\n' at the end? I write this data to an exernal text file where formatting is important as well, so it would be nicer if I don't have that \n at the end.
    I usually do this:
    Code:
    #include <string.h>
    void cleanup(char *s)
    {
        char *p;
        int c;
    
        if ((p = strchr(s, '\n')) != NULL)
            *p = '\0';
        else
            while ((c = getchar()) != EOF && c != '\n')
                ;
    }
    If fgets read everything that was to read from the input buffer, a \n will be found on s, otherwise the input buffer will still have the \n and problably more characters so the else takes care of that.

  11. #11
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    Sorry I was thinking about using a getchar() by itself before a getchar assignment if characters are to be entered after the scanf():
    Code:
                                                    scanf("%d" , &num);
                                                    getchar();
                                                    x = getchar();

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It's not effective, it's bugged. fgets does not guarantee a newline. Thus, if there isn't one, you've just nuked the last character in your word/line.



    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Feb 2006
    Posts
    155
    Code:
    if(vehicle_make[strlen(vehicle_make)-1]=='\n')
     vehicle_make[strlen(vehicle_make)-1]='\0';
    this should do the trick?

  14. #14
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    About as much as it did the trick the last time you said it.

    Quote Originally Posted by Quzah
    It's not effective, it's bugged. fgets does not guarantee a newline. Thus, if there isn't one, you've just nuked the last character in your word/line.
    Sent from my iPad®

  15. #15
    Registered User
    Join Date
    Feb 2006
    Posts
    155
    Code:
    vehicle_make[strlen(vehicle_make)-1]='\0' ;
    this is more than enough.


    a newline character is considered a valid character and it can end the reading but in anycase A null character is always appended at the end of the resulting string.

    if a newline is there vehicle_make[strlen(vehicle_make)-1] will contain the newline else it shall contain the default null character.
    Last edited by qqqqxxxx; 03-06-2006 at 12:49 AM.

Popular pages Recent additions subscribe to a feed