scanf / field lengths : using a variable / macro, C/C++

后端 未结 5 1599
伪装坚强ぢ
伪装坚强ぢ 2021-01-03 04:49

How can I use a variable to specify the field length when using scanf. For example:

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

Also, is

相关标签:
5条回答
  • 2021-01-03 05:26

    If you're using 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, it seems to be use this code with Visual Studio :

    char str[21];
    scanf("%20s", str, 21);
    
    0 讨论(0)
  • 2021-01-03 05:30

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

    I don't see one. Therefore you're going to be creating your formatting string with sprintf or whatever (if you were coding in C++ you wouldn't be using either).

    Your macro version is possible. You could 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 then you're doing what you have to do. If you're actually writing C++ and not just considering the two the same language then you have many much better options for reading data from strings.

    0 讨论(0)
  • 2021-01-03 05:30

    There's a difference here between C90, C99, and C++. In C++, you can use any integral constant expression, so

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

    is legal. In C99, the expression doesn't have to be constant; if it isn't, you get a variable length array. In the older C90, the expression couldn't include variables, so the above would not compiler, and you'd have to use

    #define MAX_STRING_SIZE 20
    char this_string[MAX_STRING_SIZE + 1];
    
    0 讨论(0)
  • 2021-01-03 05:33

    This is one of the more annoying inconsistencies 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's no equivalent for *scanf().

    Ugly as it is, I would prefer to use a separate sprintf() operation to build the format string, rather than rely on stringization macros:

    #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 torak points out, you have to go through two levels of indirection with stringization macros (as you don't want to stringize the macro, but what the macro expands to).

    0 讨论(0)
  • 2021-01-03 05:34

    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 tried to use something like STRINGIFY2 directly you would just get the string "MAX_STRING_LENGTH" instead of its value.

    For the second case you could use something like snprintf, and at least some versions of C will only let you allocate dynamically sized arrays in the heap with malloc() or some such.

    0 讨论(0)
提交回复
热议问题