28

I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter. If I do this:

scanf("%2000s %2000s", a, b);

It will follow the 1st rule but not the 2nd.
If I write:

I am smart

What I get is equivalent to:
a = "I";
b = "am";
But It should be:
a = "I";
b = "am smart";

I already tried:

scanf("%2000s %2000[^\n]\n", a, b);

and

scanf("%2000s %2000[^\0]\0", a, b);

In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want. In the 2nd one, it won't compile. According to the compiler:

warning: no closing ‘]’ for ‘%[’ format

Any good way to solve this?

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
brunoais
  • 6,258
  • 8
  • 39
  • 59

7 Answers7

50

scanf (and cousins) have one slightly strange characteristic: white space in (most placed in) the format string matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.

This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.

One way to deal with that is something like this:

scanf("%2000s %2000[^\n]%c", a, b, &c);

if (c=='\n')
    // we read the whole line
else
    // the rest of the line was more than 2000 characters long. `c` contains a 
    // character from the input, and there's potentially more after that as well.

Depending on the situation, you might also want to check the return value from scanf, which tells you the number of conversions that were successful. In this case, you'd be looking for 3 to indicate that all the conversions were successful.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
12
scanf("%2000s %2000[^\n]", a, b);
vharavy
  • 4,881
  • 23
  • 30
5

use getchar and a while that look like this

while(x = getchar())
{   
    if(x == '\n'||x == '\0')
       do what you need when space or return is detected
    else
        mystring.append(x)
}

Sorry if I wrote a pseudo-code but I don't work with C language from a while.

Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • 1
    Now I understood what you mean. Still... I think that is a bit like complicating what can be made more simply. Nevertheless, that works. – brunoais Nov 11 '11 at 19:35
3
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main(void)
{
  int i = 0;
  char *a = (char *) malloc(sizeof(char) * 1024);
  while (1) {
    scanf("%c", &a[i]);
    if (a[i] == '\n') {
      break;
    }
    else {
      i++;
    }
  }
  a[i] = '\0';
  i = 0;
  printf("\n");
  while (a[i] != '\0') {
    printf("%c", a[i]);
    i++;
  }
  free(a);
  getch();
  return 0;
}
Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • Why so complex solution? Why do so many operations that are not necessary? – brunoais Oct 19 '14 at 11:05
  • 2
    Yes brunoais You made a legit point! In my code I am doing a character by character reading which justifies the question "until",There are good optimized ways too. but for someone who started coding . My solution will be a good example on how things work. – Bharadwaj_Turlapati Oct 20 '14 at 14:48
  • 1
    @Bharadwaj_Turlapati Including and using getch() is not really a nice thing. Maybe someone is not developing or learning on Windows. – Paul Stelian Apr 24 '18 at 20:16
3

I am too late, but you can try this approach as well.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i=0, j=0, arr[100];
    char temp;
    while(scanf("%d%c", &arr[i], &temp)){
        i++;
        if(temp=='\n'){
            break;
        }
    }
    for(j=0; j<i; j++) {
        printf("%d ", arr[j]);
    }

    return 0;
}
sameera sy
  • 1,708
  • 13
  • 19
-1
#include <stdio.h>
int main()
{
    char a[5],b[10];
    scanf("%2000s %2000[^\n]s",a,b);
    printf("a=%s b=%s",a,b);
}

Just write s in place of \n :)

Web King
  • 19
  • 6
  • Also the `s` does not make sense here. `%[^\n]` already asks for all characters but a new-line. – alk Nov 25 '18 at 19:05
-2

//increase char array size if u want take more no. of characters.

#include <stdio.h>
int main()
{
    char s[10],s1[10];
    scanf("\n");//imp for below statement to work
    scanf("%[^\n]%c",s);//to take input till the you click enter
    scanf("%s",s1);//to take input till a space
    printf("%s",s);
    printf("%s",s1);
    return 0;
}
  • In your example, you are ignoring the input until the new line, you are not making safety checks, `s` will always be `\n`. Please see the accepted answer for an example answer. – brunoais Oct 30 '20 at 08:24