jane campbell
jane campbell

Reputation: 21

Use scanf with defined value

I have an array of characters in the size of SIZE

#define SIZE 50
int main(){
    char str[SIZE];
    return 0;
}

I want to read a sentence into it up to SIZE characters, using scanf.

I know I can do something such as

scanf("%50s", str);

but I can't find a way to do it with the defined value of SIZE (something like

scanf("%SIZEs", str);

I don't want to read character by character until '\0' or '\n' or SIZE -1 (for '\0') characters found.

How can I do so? Thanks!

Upvotes: 2

Views: 106

Answers (2)

chux
chux

Reputation: 153458

I want to read a sentence into it up to SIZE characters, using scanf.

Using "%s" will fail to read a sentence like "Hello World!" as "%s" does not save white-spaces.


I don't want to read character by character until '\0' or '\n' or SIZE -1 (for '\0') characters found.

  1. Instead of character by character, use fgets(): fgets(str, sizeof str, stdin); (Additional code needed to consume extra characters.)

  2. If still wanting to use scanf() to read to end of line, see following.
    Be sure the format width parameter is 1 less than the buffer size. @Oka

Example:

#define STRINGIFY_HELPER(x) #x
#define STRINGIFY(x) STRINGIFY_HELPER(x)
#define SENTENCE_MAX 50
#define SENTENCE_SIZE (SENTENCE_MAX + 1)

char str[SENTENCE_SIZE];
str[0] = '\0'; // In case input begins with a '\n'
//    v--------------------------------v Read and save non-'\n' characters.
scanf("%" STRINGIFY(SENTENCE_MAX) "[^\n]%*[^\n]", str);
//                                      ^-----^ Also eat extra non-'\n' characters. 
// Consume 1 '\n'
scanf("%*1[\n]");

More robust code would also check the return values of scanf().

Upvotes: 1

PhilMasteG
PhilMasteG

Reputation: 3185

If the length is a define like in your code, you might want to do something like this:

#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
[...]
scanf("%" STRINGIFY(SIZE) "s", str);

The #x in the macro definition actually surrounds the parameter of the macro with quotes, so this would result in:

scanf("%" "50" "s", str);

in your case. The extra indirection is necessary for the preprocessor to substitute WIDTH with "50" and not with "WIDTH".

Upvotes: 1

Related Questions