【问题标题】:scanf("%[^\n]s",a) with set size of stringscanf("%[^\n]s",a) 设置字符串大小
【发布时间】:2017-02-16 03:53:07
【问题描述】:

所以我有一个我使用的代码 scanf("%[^\n]s",a); 并且有多个 scanf 来接受不同的输入,其中一些是字符串输入。所以我知道 scanf("%[^\n]s",a) 需要输入直到到达新行,但是我想知道我的字符串最多只能容纳 10 个字符,然后在我的字符串被填充之后,但是尚未到达新行,我如何才能在进入新行之前摆脱额外的输入。我一直在考虑执行 getchar() 直到到达新行,但是为了检查我的 10 个位置是否已满,我需要使用 getchar,所以这不会弄乱我的下一个 scanf 输入吗?有人有其他方法吗?还在用 scanf() 和 getchar 吗?

【问题讨论】:

    标签: c


    【解决方案1】:

    scanf("%[^\n]s",a) 是一个常见的错误; %[ 指令不同于 %s 指令。 scanf 的问题是:

    • 一组非'\n' 字符,后跟...
    • 文字 s 字符。

    也许你打算写scanf("%[^\n]",a)?注意删除的s...

    您可以使用* 修饰符来禁止对指令的赋值,例如scanf("%10[^\n]", a); 后跟scanf("%*[^\n]"); 读取并丢弃到下一个换行符,getchar(); 读取并丢弃该换行符:

    scanf("%10[^\n]", a);
    scanf("%*[^\n]");     // read and discard up to the next newline
    getchar();            // read and discard that newline
    

    正如所指出的,可以连接两个格式字符串以减少对scanf 的调用次数。为了文档,我以这种方式写了我的答案,我将保持原样。此外,我认为优化的尝试可以忽略不计。探查器可能会指出实际场景中更重要的优化瓶颈。

    【讨论】:

    • 为什么不将两个scanf 合二为一。再调用一次,堆栈中就会有更多空间。
    • @Meninx 我不相信你。请在 C 标准草案 n1570.pdf 中告诉我,这个“堆栈”在哪里提到?
    • 第一个 scanf 会读取到我的字符串的大小,然后它会丢弃之后的任何内容直到新行,getchar 会移动到下一行,对吗?但是,如果用户输入的数据小于 10 并且我也想从下一行读取数据,那么 scanf("%*[^\n]");和 getchar();跳过第一个输入之后的一些输入?
    【解决方案2】:

    您可以使用这种格式保存前 10 个字符并保留输入的下一行:

    scanf("%10[^\n]%*[^\n]",a);
    getchar();
    

    【讨论】:

    • 所以如果输入的第一行超过10个字符,这样它会跳过该行的其余字符并转到下一行吗?我是 C 新手,所以我只是对格式感到困惑。
    • 没错,该行的其余字符将被跳过。
    • 当%*[^\n] 读取和丢弃的集合为空时,这不会读取并丢弃'\n',因为该空集合会导致失败,从而导致scanf 立即返回。引用:“匹配一组预期字节(扫描集)中的非空字节序列。”和“成功完成后,这些函数应返回成功匹配和分配的输入项的数量;如果早期匹配失败,此数字可以为零。” -- opengroup fscanf manual
    • 我同意,如果下一个scanf 将使用%[,那么getchar() 是包含此案例的正确选择。
    • @NishR 如果您是 C 新手,您可能应该完整阅读(并理解)the opengroup fscanf manual...即使您不理解 parts坚持下去!
    猜你喜欢
    • 2011-12-31
    • 2021-10-26
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 2020-07-20
    • 1970-01-01
    相关资源
    最近更新 更多