scanf()可变长度说明符

时间:2014-08-20 17:13:48

标签: c scanf

如何使用变量指定应该读入的最大字符数scanf()

例如,使用printf()您可以使用* like so

#define MAXVAL 5
printf("Print at maximum MAXVAL chars: %.*s\n", MAXVAL, "myStringHere");

这只会打印5个字符,如何才能使scanf仅在MAXVAL中读取? MAXVAL必须用作长度说明符。我不能简单地做

scanf("%5s", string);

现在我只能考虑使用scanf读取大型数组,然后使用ssprintf将字符串存储到我的长度限制字符串中。然而,使用长度说明符会更容易。

4 个答案:

答案 0 :(得分:16)

您可以使用C预处理器来帮助您。

#define STR2(x) #x
#define STR(X) STR2(X)
scanf("%" STR(MAXVAL) "s", string);

处理器将"%" STR(MAXVAL) "s"合并到"%5s"

答案 1 :(得分:5)

#include <stdio.h>

#define MAXLEN 5
#define S_(x) #x
#define S(x) S_(x)

int main(void){
    char string[MAXLEN+1];

    scanf("%" S(MAXLEN) "s", string);
    printf("<%.*s>\n", MAXLEN, string);
    return 0;
}

答案 2 :(得分:2)

你做不到。您需要使用scanf()以外的其他内容。一个好的和受欢迎的选择是fgets(),虽然它的语义略有不同:fgets()将读取一行输入,而带有scanf()的{​​{1}}将读取空格分隔的字符序列

要使用%s,您需要以下内容:

fgets()

如果由于某种原因您真的想使用fgets(string, MAXVAL, stdin); ,请查看以下问题:How to prevent scanf causing a buffer overflow in C?

答案 3 :(得分:1)

Kernighan and Pike建议使用snprintf()创建格式字符串。 我将这个想法发展成了一种安全读取字符串的方法:

void scan_string(char * buffer, unsigned length) {
    char format[12]; // Support max int value for the format %<num>s
    snprintf(format, sizeof(format), "%%%ds", length - 1); // Generate format
    scanf(format, buffer);
}

int main() {
  char string[5];
  scan_string(string, sizeof(string));
  printf("%s\n", string);
}