3
votes

I need a scanf() call to accept whitespace (no tabs or newlines, just ' ' space glyphs).

char buffer[2048];
scanf(" %2048[0-9a-zA-Z ]s", buffer);

This format specifier I got from the answer to this question:

how-do-you-allow-spaces-to-be-entered-using-scanf

While it accepts the first sequence of input just fine, it terminates where the first whitespace character is, with a null character. What's going on? Am I perhaps using the wrong format?

I should say, I'm using scanf() here because safety isn't a concern; I'm the only person who'll ever use this particular program, and the input is rigidly formatted.

4
should this be something like scanf("%^[\n ]s",buffer);Satya
need to add & before bufferSuji
@SujithKarivelil - buffer is already a pointer (from the array script), so it's okayAnne Quinn
The buffer isn't a pointer - it's an array reference, which is not the same thing. However, the array reference will decay to a pointer when used in this manner, so it is correct to not include the &.Timothy Jones

4 Answers

6
votes

Use scanf("%[^\n]",buffer);. It will accept white space.

Sample program-

int main()
{
    char buffer[2048];
    printf("Enter the string\n");
    scanf("%[^\n]",buffer);

    printf("%s\n", buffer);
    return 0;
}

output-

root@sathish1:~/My Docs/Programs# ./a.out 
Enter the string
abc def ghi ijk
abc def ghi ijk
root@sathish1:~/My Docs/Programs# 
2
votes

Scanf isn't good for dealing with format that you're expecting to have a particular amount of whitespace. From the scanf man page:

White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.

And:

[

Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating NUL character. The usual skip of leading white space is suppressed.

This means you can do something like

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

which says: "Read everything but the newline at the end of the string".

Or, if you're wanting to skip the first space, you can do:

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

This says "Read but ignore a space character, then read everything else into buffer".

1
votes

While you can use scanf, if you are reading lines of text, getline is preferred and provides the advantage of dynamic memory allocation (when line = NULL). getline does read/save the newline character, so if that isn't desired, it can be easily stripped. The following example illustrates the point:

#include <stdio.h>

int main (void) {

    char *line = NULL;
    ssize_t read = 0;
    size_t n = 0;

    printf ("\nEnter a line of text: ");
    read = getline (&line, &n, stdin);
    line [read - 1] = 0;  /* strip newline from string (optional) */
    read--;

    printf ("\n  read '%zd' characters: '%s'\n\n", read, line);

    return 0;

}

output:

./bin/getln

Enter a line of text: this is a line of text   with  white ..   ..  space.

  read '52' characters: 'this is a line of text   with  white ..   ..  space.'
0
votes

fgets(string, sizeof(string), stdin) will accept or scanf("%[\n]s",string); will accept