Douglas Gaskell
Douglas Gaskell

Reputation: 10030

Issues ignoring spaces with scanf when using multiple scanf's in C

I'm trying to use scanf multiple times in a small program to grab inputs that are guaranteed to have spaces. From the multiple threads I've browsed though it seems like scanf("%[^\n]", string); is the way to get it to ignore spaces. This works, for one line, but any other scanf's after that line don't go through and their respective strings put out the following:

Action: J���J
 Resolution: J:F�J�B�J

Here is a bit of example code that I thought would work, but does not.

#include <stdio.h>

int main(void)
{   
    char str1[100];
    char str2[100];

    printf("Situation?\n");
    scanf("%[^\n]", str1);

    printf("Action Taken?\n");
    scanf("%[^\n]", str2);

    printf("Situation: %s\n",str1);
    printf("Action: %s\n",str2);
}

If I input "Just a test" when prompted for the situation the following happens:

Situation?
just a test
Action Taken?
Situation: just a test
Action: ��_��?�J.N=��J�J�d�����J0d���8d��TJ�J

Any suggestions or solutions (excluding fgets)? An explanation of what's happening would be great as well.

Edit: The solution over at scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?

Adding in the char* fmt = "%[^\n]%*c"; worked 100%.

char* fmt = "%[^\n]%*c";

  printf ("\nEnter str1: ");
  scanf (fmt, str1);
  printf ("\nstr1 = %s", str1);

  printf ("\nEnter str2: ");
  scanf (fmt, str2);
  printf ("\nstr2 = %s", str2);

  printf ("\nEnter str3: ");
  scanf (fmt, str3);
  printf ("\nstr2 = %s", str3);

  printf ("\n");

Upvotes: 0

Views: 2519

Answers (4)

Tony
Tony

Reputation: 6148

Solution one: Using scanf

If you still want to read it by scanf, the answer provided by @chux and @BLUEPLXY is good enough. Like:

 scanf(" %[^\n]", str);  //notice a space is in the formatted string

or

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

Solution two: Using getline()(although it is a POSIX extension)

Because using gets() and 'fgets()` are unreliable sometimes.

Upvotes: 0

chux
chux

Reputation: 153338

Number of approaches:

Rather than the following which does not consume the Enter or '\n' (which is the problem):

scanf("%[^\n]",str1);
  1. Consume the trailing newline. "%*1[\n]" will only consume 1 '\n', but not save it.

    scanf("%99[^\n]%*1[\n]" ,str1);
    
  2. Consume the trailing newline on the next scanf(). The " " consume previous and leading white-space.

    scanf(" %99[^\n]", str1);
    
  3. Use fgets(), but of course, this is not scanf(). The best method.

    fgets(str1, sizeof str1, stdin);
    

Whatever solution, limit the maximum charcters read and check the function's return value.

    if (fgets(str1, sizeof str1, stdin) == NULL) Handle_EOForIOError();

Upvotes: 2

BLUEPIXY
BLUEPIXY

Reputation: 40145

change

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

to

scanf("%[^\n]%*c", str1);//consume a newline at the end of the line

Upvotes: 3

NoDataFound
NoDataFound

Reputation: 11949

I don't have an immediate answer for you problem, why don't you simply use fgets (or even gets) if you want a line of input ?

Upvotes: 1

Related Questions