0

How can enter two strings with scanf in C?, I want to use them as follow:

#include <stdio.h>
#include <string.h>
main()
{
  char kid[25];
  char color[10];
  scanf( "%24[^\n]", kid); // kid name
  scanf( "%9[^\n]", color);
  printf("%s\'s favorite color is %s.\n", kid, color);
  return 0;
}
Vega
  • 27,856
  • 27
  • 95
  • 103
T.Saleh
  • 35
  • 6
  • 2
    And what is the problem with the code you show? Please [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask), then *edit your question* to elaborate on the problem you're having. – Some programmer dude Oct 30 '17 at 16:06
  • 2
    `"%24[^\n]"` --> `"%24[^\n]%*c"` – BLUEPIXY Oct 30 '17 at 16:07
  • 2
    And why use a function that isn't well-suited for the job? @BLUEPIXY's solution "works", but you have no way to recover if the input is too long (a character is dropped). Just use `fgets()` or, if you can tie your code to POSIX systems, `getline()`. –  Oct 30 '17 at 16:31
  • @BLUEPIXY: The trouble with that is that nothing is read if the user inputs an empty line (ie a line with just `\n` on it). The `"%24[^\n]"` will not match and thus the `scan()` will exit before processing `"%*c"`. Thus leaving the line unread. This will repeat with `color` and even if you enter a color it will not be read as the kids name will block it from reaching color. – Martin York Oct 30 '17 at 17:51
  • @LokiAstari I know that. – BLUEPIXY Oct 30 '17 at 17:59

2 Answers2

2

You are reading input till a \n into kid with the first scanf(). But that scanf() won't read the \n and it will remain in the input buffer.

When the next scanf() is done, the first character it sees is the \n upon which it stops reading before anything is written to color.

You could do

scanf("%24[^\n] ", kid);
scanf("%9[^\n]", color);

The space after the [^\n] will read a white-space character like \n.

If %*c is used like

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

%*c in scanf() will cause a character to be read but it won't be assigned anywhere. * is the assignment suppressing character. See here.

But if exactly 25 characters are given as input before a \n, the %*c will just read the last character leaving the \n still in the input buffer.

If you can use a function other than scanf(), fgets() would do well.

Do

fgets(kid, sizeof(kid), stdin);

but remember that fgets() would read the \n as well into kid. You could remove it like

kid[strlen(kid)-1]='\0';

Due to this \n being read, the number characters that are read will be effectively 1 less.

J...S
  • 5,079
  • 1
  • 20
  • 35
  • 1
    Thank you. it solved my problem, – T.Saleh Oct 31 '17 at 08:00
  • @Felix I edited it. – J...S Oct 31 '17 at 08:50
  • Thank you for your answer, Im new to the C language, I wrote my final code as follow: char kid[8],color[10]; printf("The fourth kid name is: "); fgets(kid, sizeof(kid), stdin); printf("The fourth color name is: "); fgets(color, sizeof(color), stdin); printf("%s\'s favorite color is %s.\n",kid,color); return 0; but after I run and enter the name/color I got answer like: Mike' s favorite color is Black . the kid name and the dot at the end is on differen lines. How can I solve it? – T.Saleh Oct 31 '17 at 09:06
  • @MesopotamianLion `fgets()` will read in the trailing `\n`. You can remove it the way given in the last part of the answer. – J...S Oct 31 '17 at 09:46
  • Sorry but I didnt get how to use "kid[strlen(kid)-1]='\0';". What I want is that when I run the code it will ask me first about the kid name, then in new line will ask me for the color. After typing the color and pressing enter it should give me for example (Mike's favorrite color is Green.) – T.Saleh Oct 31 '17 at 10:12
  • @MesopotamianLion Not sure that I understand what you mean. – J...S Oct 31 '17 at 10:15
  • I dont know how to use and where to put the line kid[strlen(kid)-1]='\0'; – T.Saleh Oct 31 '17 at 10:55
  • @MesopotamianLion Right after the `fgets()` used for reading `kid`. – J...S Oct 31 '17 at 16:28
0

Your problem is that this line does not read the \n character from the stream.

scanf( "%24[^\n]", kid); // kid name

So you read the kids name but don't remove the newline character. So the next scanf() just sees a return character on the input stream and thus you will get an empty color.

if (scanf( "%24[^\n]", kid) == 1) { // kid name
    char term;
    while ( scanf( "%c", &term) == 1 && term != '\n') {
        /* read characters until you can't read or you reach the end of line */
    }
}
else {
    /* Error */
}

If the user input a kids name longer than 24 characters then you need to read and throw away these characters (or do some appropriate error handling). The end of the kids name is marked by the '\n' character.

Note: The while loop above is for illustration purposes. There are better way.

if (scanf( "%24[^\n]", kid) == 1) { // kid name
   scanf("%*[^\n]");  // Note. You can not use "%*[^\n]\n". This will fail if just a newline
   scanf("\n");       // So split into two lines (the first may read nothing).
}
else {
    /* Error */
}
Martin York
  • 257,169
  • 86
  • 333
  • 562