0

I have just started learning C. Here is some sample code I was experimenting with. It is just meant to get a users name. If I enter a string for the first answer which is expecting a char, the first letter is saved to middleInitial, but instead of the rest of the string being ignored is read and saved by the subsequent scanf. This means that entering "Jacob" and then "Pat Smith" would result in the output of "Your name is acob J Pat" Why is this happening?

char middleInitial; 
printf("What is your middle initial?");

scanf(" %c", &middleInitial);

char firstName[30], lastName[30];

printf("What is your name? ");

scanf(" %s %s", firstName, lastName);

printf("Your name is %s %c %s", firstName, middleInitial, lastName);
algo
  • 3
  • 1

3 Answers3

0

The reason is the remaining characters which are not fetched by the first scanf stay in the STDIN buffer which are then fectehed by the subsequent scanf. flush STDIN before you read firstname and lastname. Since fflush is not a reliable way of deleting unwanted characters in the STDIN buffer a manual way of doing it is explained here.

Community
  • 1
  • 1
sumithdev
  • 331
  • 1
  • 8
  • 1
    The advice to `fflush(stdin)` is platform specific — for more information, see [Using `fflush(stdin)`](http://stackoverflow.com/questions/2979209/using-fflushstdin). – Jonathan Leffler Jan 19 '15 at 02:48
0

According to the code:

scanf(" %c", &middleInitial);

middleInitial get the only first character of your input.

For example: yout inputed "Jacob" and then "John Smith":

middleInitial = J
firstName = acob
lastName = John

You should try:

char middleInitial;
char str[30];
printf("What is your middle name?");

scanf(" %c", &middleInitial); // get "J"
scanf(" %s", &str);  // get "acob"
char firstName[30], lastName[30];

printf("What is your name? ");

scanf(" %s %s", firstName, lastName);

printf("Your name is %s %c %s", firstName, middleInitial, lastName);
null
  • 161
  • 5
0

I have some advices for string (char*) usage in C. First, as sumithdev said, use fflush(stdin) to clean input stream buffer before input any piece of information. Second, try to use uniform style for storing all string data. For example, your middleInitial also can be defined as array of char but may me length of 2 (middleInitial[0] will be a character, and middleInitial[1] will be a ‘\0’). And the last advice – try to use robust functions to prevent memory violation and data lost. For code:

scanf(" %s %s", firstName, lastName);

I see potential problems:

a) in general first name or last name of user can be more than one word, but one %s in scanf read characters until space;

b) first name or last name can be greater than 29 letters and 30 elements of array would be not enough to store input, this will lead to runtime problems;

c) when you want to change the order for input different parts of name or add some check, you will have lots of hard modification in your code.

Consider the following version:

char middleInitial[2]; 
char firstName[30], lastName[30];
// asking for middle part
printf("What is your middle initial? ");
fflush(stdin); // delet all previous inputs
scanf("%1s", middleInitial); // wait new inputs and take only 1 character
// asking for first part
printf("What is your first name? ");
fflush(stdin);
scanf("%29s", firstName); // wait new inputs and take not more than 29 characters
// asking for last part
printf("What is your last name? ");
fflush(stdin);
scanf("%29s", lastName); // wait new inputs and take up to 29 characters
// output result
printf("Your name is %s %s %s\n", firstName, middleInitial, lastName);

And also try to use fgets instead of scanf. For example:

fflush(stdin);
fgets(firstName, 30, stdin); // this allows input of strings with spaces
// but adds 'new line' (\n) in the end of string
VolAnd
  • 6,367
  • 3
  • 25
  • 43