使用具有定义值的scanf

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

我有一个大小为 SIZE 的字符数组

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

我想使用 scanf 读入一个最多 SIZE 个字符的句子。

我知道我可以做一些事情,比如

scanf("%50s", str);

但我找不到一种方法来使用定义的 SIZE 值(类似于

scanf("%SIZEs", str);

我不想逐字符读取,直到“ ”或“ ' 或 SIZE -1(表示“ ”)字符找到。

我该怎么做? 谢谢!

arrays c string scanf
3个回答
1
投票

如果长度是像代码中那样的定义,您可能需要执行以下操作:

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

宏定义中的

#x
实际上是用引号将宏的参数括起来,所以这会导致:

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

就你的情况而言。预处理器需要额外的间接寻址来用“50”而不是“WIDTH”替换 WIDTH。


0
投票

这应该有效:

char format[10];
sprintf(format, "%%%ds", SIZE);
scanf(format, str);

说明:

%% - escaped percent sign
%d - Format specifier for SIZE
s  - The trailing s.

结果

format
包含
%50s


0
投票

我想使用 scanf 读入一个最多 SIZE 个字符的句子。

使用

"%s"
将无法读取像“Hello World!”这样的句子。因为
"%s"
不保存 空白


我不想逐字符读取,直到“ ”或“ ' 或 SIZE -1(表示“ ”)字符找到。

  1. 不要使用逐个字符,而是使用

    fgets()
    fgets(str, sizeof str, stdin);
    (需要额外的代码来消耗额外的字符。)

  2. 如果仍想使用

    scanf()
    读取到行尾,请参阅以下内容。
    确保 format width 参数比缓冲区大小小 1。 @奥卡

示例:

#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]");

更健壮的代码还会检查

scanf()
的返回值。

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