I have learned a few programming languages and am now in the beginning stages of teaching myself C with "C Programming, Second Edition for the absolute beginner".

I'm enjoying the book but have run into some difficulties in the second chapter exercies. The exercise states as follows:

Create a program that prompts a user for her name. Store the user's name using the scanf() function and return a greeting back to the user using her name.

Simple enough in another language where I could just declare a string and prompt the user to enter said string. This is the second chapter of the book and strings are not covered until chapter 8. Through online research and this forum I have created this solution:

// Ex. 2.3, Name
// This program prompts the user to enter their name and then displays a greeting to
// the user utilizing the name entered.

#include <stdio.h>

int main()
{ // begin main()

    char dump, stringName[40];

    printf("Please enter your name: ");
    scanf("%[^\n]", stringName);
    scanf("%c", &dump);

    printf("\nHello %s\n", stringName);

    return 0;
} // end main()

It works though I don't understand the "dump" aspect or the [^\n] from above. The main question I have is how was I supposed to create a solution to this problem without using something that hasn't been taught yet and won't be for numerous chapters.

Edited 4 Years Ago by deceptikon: Snipped personal information (author's name)

Probably you were expected to assume the name didn't have any spaces in it, and do

char name[100]; scanf("%99s\n", name);

The way the code in your post works is that it matches a sequence of characters that are not \n. The %[^\n] format specifier works a bit like a regex character class. For example, %[ac-e] would match one or more characters that are a, c, d, or e. %[^ac-e] would match one or more characters that are not a, c, d, or e. Then the line involving dump should supposedly eat the \n at the end of the stream. That of course assumes the user inputs less than 40 characters, otherwise it writes past the end of the array and makes your program crash in interesting ways.

scanf("%[^\n]", stringName);

[^\n] represents that when a user press enter then the scanf function must be terminated.
for ex- if you want to terminate your program at a ";"(without quotez) sign ou can use

scanf("%[^;]",stringname);

Comments
I never knew that before. tnx :)

You can use a character array to do this task.
and scanf("%[^\n]",strName); means that the user can enter a name and if he completes his name he need to enter a new line.
by default a scanf() considers a space character as a delimiter.
By using the [^\n] , we are changing the delimiter to a new line character.

#include <stdio.h>
#include<conio.h>
int main()
{ // begin main()

    char stringName[40];

    printf("Please enter your name: ");
   // scanf("%[^\n]", stringName);
    scanf("%s", stringName);

    printf("\nHello %s\n", stringName);
    getch();
    return 0;
} // end main()

there is no need for dump and all..simply u get a string using %s..that's it

there is no need for dump and all..simply u get a string using %s..that's it

Okay, now type a first and last name. You introduced an error since the original code was retrieving a full line of input rather than a single word.

Ideally one would use fgets() for this purpose, but the original question was why the code was the way it was rather than how to make it better. And the answer is that the %[^\n]" scanset will read everything up to but not including the trailing newline character. So something else must be done to extract that newline character, hence a second call to scanf() that reads only a single character.

A sneaky way of doing the same thing would be:

scanf("%[^\n]%*c", stringName);

But all in all the best approach is fgets().

But all in all the best approach is fgets().

Agree -- scanf("%[^\n]%*c") is awkward and difficult to read.

Edited 3 Years Ago by Ancient Dragon

Agree -- scanf("%[^\n]%*c") is awkward and difficult to read.

It's also difficult to error check without using a dummy variable. A more robust solution with scanf() would actually finish with getchar():

if (scanf("%[^\n]", s) == 1) {
    if (getchar() != '\n') {
        // Error: expected a newline
    }
}
else {
    // Error: EOF or bad stream state 
}
This article has been dead for over six months. Start a new discussion instead.