Scanf / field length: using variable / macro, C / C ++

How can I use a variable to indicate the length of a field when using scanf. For instance:

char word[20+1]; scanf(file, "%20s", word); 

Also, is it correct to use 20 + 1 (since at the end you need to add \ 0?). Instead, I would like to have something like:

 #define MAX_STRING_LENGTH 20 

and then

 char word[MAX_STRING_LENGTH+1]; scanf(file, "%"MAX_STRING_LENGTH"s", word); // what the correct syntax here..? 

Is it possible? How about if it is a type variable:

 int length = 20; char word[length+1]; scanf(file, "%" length "%s", word); // what the correct syntax here..? 

Thanks.

+4
source share
5 answers

The following should do what you need for the first case.

 #define MAX_STRING_LENGTH 20 #define STRINGIFY(x) STRINGIFY2(x) #define STRINGIFY2(x) #x { ... char word[MAX_STRING_LENGTH+1]; scanf(file, "%" STRINGIFY(MAX_STRING_LENGTH) "s", word); ... } 

NOTE. Two macros are required because if you try to use something like STRINGIFY2 directly, you simply get the string "MAX_STRING_LENGTH" instead of its value.

In the second case, you can use something like snprintf, and at least some versions of C will allow you to allocate arrays with dynamic heap size using malloc() or some such.

+6
source

http://www.manpagez.com/man/3/scanf/

I do not see it. Therefore, you will create your format string using sprintf or whatever (if you were in C ++ you would not use either).

Your macro version is possible. You can look in the boost preprocessor library for STRINGIFY and either use it or see how it works.

Are you really writing in C ++ here or in C? If in C you are doing what you need to do. If you are actually writing C ++ and not just looking at two identical languages, then you have many, much better options for reading data from strings.

0
source

If you use regular scanf (Linux), you have two solutions:

 #define MAX_STRING_LENGTH_STR "20" scanf(file, "%"MAX_STRING_LENGTH_STR"s", word); 

OR

 #define MAX_STRING_LENGTH 20 sprintf(format, "%%%ds", MAX_STRING_LENGTH); scanf(file, format, word); 

However, this code seems to be used with Visual Studio :

 char str[21]; scanf("%20s", str, 21); 
0
source

This is one of the most annoying discrepancies between the *printf() and *scanf() families. For some reason, you can use wildcards in *printf() conversion specifiers and provide values ​​for them in the argument list, but there is no equivalent for *scanf() .

Be that as it may, I would prefer to use a separate sprintf() operation to build a format string, rather than relying on macros as a string:

 #define LENGTH 20 char word[LENGTH+1]; char format[5]; sprintf(format, "%%%ds", LENGTH); fscanf(file, format, word); 

At least this is somewhat intuitive; as Thorak points out, you need to go through two levels of indirection using string macros (since you don’t want to screw the macro, but that extends the macro).

0
source

Here is the difference between C90, C99 and C ++. In C ++, you can use any integral constant expression, therefore

 const int max_string_size = 20; int this_string[max_string_size + 1]; 

is legal. In C99, the expression does not have to be constant; If this is not the case, you get an array of variable length. In older C90, an expression cannot include variables, so there will be no compiler above, and you will have to use

 #define MAX_STRING_SIZE 20 char this_string[MAX_STRING_SIZE + 1]; 
0
source

Source: https://habr.com/ru/post/1316442/


All Articles