scanf() 可变长度说明符

问题描述 投票:0回答:4

如何使用变量来指定应读入的最大字符数

scanf()

例如使用

printf()
您可以像这样使用 *

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

这只会打印5个字符,我怎样才能使

scanf
只在MAXVAL中读取? MAXVAL 必须用作长度说明符。我不能简单地做

scanf("%5s", string);

现在我只能想到使用

scanf
读入一个大数组,然后使用
ssprintf
将字符串存储到我的长度有限的字符串中。然而,使用长度说明符会容易得多。

c scanf
4个回答
26
投票

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

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

处理器将

"%" STR(MAXVAL) "s"
组合到
"%5s"


6
投票
#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;
}

5
投票

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

void scan_string(char *buffer, unsigned length) {
    char format[16]; // Max int (10) + %, s & null-terminator (3)
                     // Rounded up to the closes power of 2
    snprintf(format, sizeof(format), "%%%ds", length - 1);
    scanf(format, buffer);
}

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

2
投票

你不能。您需要使用

scanf()
以外的其他东西。一个不错且流行的选择是
fgets()
,尽管其语义略有不同:
fgets()
将读取一行输入,而
scanf()
%s
将读取空格分隔的字符序列。

要使用

fgets()
,您需要类似以下内容:

fgets(string, MAXVAL, stdin);

如果出于某种原因你真的想使用

scanf()
,请看一下这个问题:如何防止 scanf 导致 C 中的缓冲区溢出?

© www.soinside.com 2019 - 2024. All rights reserved.