【问题标题】:scanf: template with macro (#define constant) insidescanf:带有宏(#define 常量)的模板
【发布时间】:2013-10-16 17:22:32
【问题描述】:

我有一些类似这里的代码:

#define MAXSIZE 100

int main() {
    char str[MAXSIZE+1];
    scanf("%100s", str);
    ...

问题是我仍然有“幻数”100,尽管定义了 MAXSIZE。 有没有办法将 MAXSIZE 正确“插入”到 scanf 格式字符串中? (纯 C,c-99 标准)

【问题讨论】:

  • 一定要用scanf吗?如果没有,请尝试fgets()

标签: c scanf


【解决方案1】:

有,但最好使用fgets()

if (fgets(str, sizeof str, stdin) != NULL) {
    // process input
}

这样做的好处(除了毫无疑问的可读性提升)是fgets() 正确地处理了大小, i。 e.它解释了终止 0 字符(scanf() 没有),因此您不必在声明缓冲区时将大小加一。它也总是为您终止数组。更不容易出错。


至于最初的问题:尝试通常的“字符串化”技巧:

#define REAL_STRINGIFY(x) #x
#define STRINGIFY(x) REAL_STRINGIFY(x)

scanf("%" STRINGIFY(MAXSIZE) "s", str);

但这很丑,不是吗?

【讨论】:

  • 很丑!没有人想去想它。
  • @hacks 但我喜欢 :),一种方法是 OP 可以声明一个新宏 #define MAX "100"
  • @hacks 没错。真恶心。
  • 1. fgets 与 scanf("%s" 不同,例如 scanf 在空白处停止。对 fgets 调用乘法次数(带有空白检查)看起来可能是性能较低的解决方案。2. stringify 真的很难看 :)。不过谢谢,我不知道这种伎俩。
  • @Nyxo 在现实世界中,我们解决实际存在的问题。在这里,OP 正在读取标准输入。没有其他的。没有人会以足够快的速度打字,让fgets() 变得足够慢。无论如何,如果它很慢怎么办?说真的,谁在乎?它是安全的,这是更重要的数量级。也不需要需要停止空间行为。如果你可以读一整行,那么你也可以使用strchr()strtok_r() 或其他任何东西来解析它——这无疑比依赖I/O 函数来做这件事要好。这只是对 I/O 库的滥用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2010-10-20
相关资源
最近更新 更多