Thread: Beginner Question: Problem with scanf and strings. Help!

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    28

    Beginner Question: Problem with scanf and strings. Help!

    First off how does scanf know that this: %[^\n] is supposed to be formatted for a String? Shouldn't %s need to be in there? According to the syntax it's not supposed to be.

    Anyway, my real question is when I run this program (below) it lets me type in my first name, but then when I press Return it skips over letting me enter my last name and shows this:

    Code:
    What is your FIRST name: Bryan
    What is your LAST name: Your FULL name is Bryan  and it is 6 long.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main (int argc, const char * argv[]) {
    
    	char		firstname[31];
    	char		lastname[31];
    	char		fullname[63];
    	
    	printf( "What is your FIRST name: " );
    	scanf( "%[^\n]", firstname );      // accepts everything until it sees a \n
    	
    	printf( "What is your LAST name: " );
    	scanf( "%[^\n]", lastname );      // accepts everything until it sees a \n
    	
    	strcpy( fullname, firstname );
    	strcat( fullname, " " );
    	strcat( fullname, lastname );
    	
    	printf( "Your FULL name is %s and it is %d long.", fullname, strlen(fullname) );
    		  
        return 0;
    }

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    See this link for information about scanf(): scanf [C++ Reference]

    In short, the characters between the brackets, ^\n, tells scanf() to suck in everything EXCEPT a newline character. The NEWLINE character is left in the input buffer.

    When the next scanf() is issued, it reads everything up to the NEWLINE, which is nothing, and returns immediately.

    If you use the bracket notation, you'll next an extra line of code to remove the NEWLINE from the input buffer.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    scanf( "%[^\n]", firstname ); // accepts everything until it sees a \n
    Yep. Now check your docs for this angle:

    scanf( "%[^\n]%*c", firstname );
    Or, you could just use %s, and then, as Dino is trying to say, remove the '\n' from your string if desired.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Jul 2009
    Posts
    28

    Question ok, i tried adding this (still doesn't work)

    I figured using a fflush(stdin); would clear the buffer but it doesn't seem to make a difference... I'm clueless how to get this working as expected

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main (int argc, const char * argv[]) {
    
    	char		firstname[31];
    	char		lastname[31];
    	char		fullname[63];
    	
    	printf( "\nWhat is your FIRST name: " );
    	scanf( "%[^\n]", firstname );
    	fflush(stdin);                       // this doesn't seem to work
    	
    	printf( "\nWhat is your LAST name: " );
    	scanf( "%[^\n]", lastname );
    	
    	strcpy( fullname, firstname );
    	strcat( fullname, " " );
    	strcat( fullname, lastname );
    	
    	printf( "\nYour FULL name is %s and is %d characters long.", fullname, strlen(fullname) );
    		  
        return 0;
    }

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by lucidrave View Post
    I figured using a fflush(stdin); would clear the buffer
    Never use fflush(stdin) -- it is not defined by the C standard:
    [#2] If stream points to an output stream or an update
    stream in which the most recent operation was not input, the
    fflush function causes any unwritten data for that stream to
    be delivered to the host environment to be written to the
    file; otherwise, the behavior is undefined.
    Read my previous post; the "*" flag means ignore. In the context of your scanf line, that %c will be the newline.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Jul 2009
    Posts
    28

    thanks

    ohh ok... so it means ignore any characters after it sees the new line?

    (in this code anyway)

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by lucidrave View Post
    ohh ok... so it means ignore any characters after it sees the new line?
    (in this code anyway)
    No, it means ignore the newline, which is a single character ('\n'). So if you typed:

    mk27\n

    (the newline being because of the enter key), and you capture everything up to but not including the newline with %[^\n], '\n' is left in the buffer. %*c captures one more character and throws it away; because of the context, in this case that character would have to be the newline (get it?).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Jul 2009
    Posts
    28
    I guess what's confusing me is I thought %[^\n] was to ignore the new line, but then %*c also ignores the new line. isn't that redundant?

    if %[^\n] doesn't work by itself should I not use it?

    Also is the * part of %*c acting as a "wildcard"? It's a bit confusing know what purpose it serves since it could be multiply (which wouldn't make any sense in this case) or referencing a pointer.

    Quote Originally Posted by MK27 View Post
    No, it means ignore the newline, which is a single character ('\n'). So if you typed:

    mk27\n

    (the newline being because of the enter key), and you capture everything up to but not including the newline with %[^\n], '\n' is left in the buffer. %*c captures one more character and throws it away; because of the context, in this case that character would have to be the newline (get it?).

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by lucidrave View Post
    I guess what's confusing me is I thought %[^\n] was to ignore the new line, but then %*c also ignores the new line. isn't that redundant?
    As mentioned, %[^\n] means "get everything that isn't a newline". If you do that, well, the newline is still there since you got everything that wasn't a newline. You need to now do something with that newline, instead of what you seem to be doing which is "ignore it and hope that it goes away".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings in Scanf function
    By dcwang3 in forum C Programming
    Replies: 21
    Last Post: 09-11-2008, 03:47 AM
  2. scanf for strings?
    By pobri19 in forum C Programming
    Replies: 7
    Last Post: 05-31-2008, 03:47 AM
  3. scanf problem
    By a1dutch in forum C Programming
    Replies: 8
    Last Post: 04-19-2005, 04:14 AM
  4. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  5. Problem with scanf input
    By ejpjoker in forum C Programming
    Replies: 4
    Last Post: 04-29-2004, 08:28 PM

Tags for this Thread