为什么不是 scanf("%*[^\n]\n");和 scanf("%*[^\n]%*c");清除悬挂的换行符?

2024-01-30

拨打电话后scanf("%d", &variable);我们留下了一个换行符挂在stdin,应在调用之前清除fgets,或者我们最终给它提供一个换行符并使其过早返回。

我找到了建议使用的答案scanf("%*[^\n]%*c");第一次致电后scanf放弃换行符和其他建议使用scanf("%*[^\n]\n");。理论上,两者都应该有效:第一个会消耗所有不是换行符的内容(但不包括换行符本身),然后消耗exactly一个字符(换行符)。第二个将消耗所有不是换行符(不包括它)的内容,然后\n,一个空白字符,将指示scanf读取每个空白字符,直到第一个非空白字符。

然而,尽管我认为这些方法在某些答案中有效,但我无法让它们在这里工作(代码如下)。

为什么两者都没有scanf方法有效吗?

测试于: Ubuntu Linux -gcc 5.4.0

scanf("%*[^\n]\n");方法:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin?
    scanf("%*[^\n]\n");

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

Output:

$ ./bug 
Write number: 
2
Write phrase: 


You wrote:2 and "
"

scanf("%*[^\n]%*c");方法:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin?
    scanf("%*[^\n]%*c");

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

Output:

$ ./bug2 
Write number: 
3
Write phrase: 


You wrote:3 and "
"

以下方法是唯一能够按预期方式工作的方法:

工作方式:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin!
    int c;
    while((c = getchar()) != '\n' && c != EOF){
        //Discard up to (and including) newline
    }

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

Output:

$ ./notbug 
Write number: 
4
Write phrase: 
phrase :D


You wrote:4 and "phrase :D
"

基本问题是 scanf 模式%[^\n]火柴一个或多个不是换行符的字符。所以如果下一个字符is换行符,该模式将失败并且scanf将立即返回而不阅读任何内容。添加一个*并没有改变这个基本事实。所以事实证明你不能只用一次调用来做到这一点,你需要两次:

scanf("%*[^\n]"); scanf("%*c");

请注意,在扫描模式中放入一个空的换行符几乎总是没有用的——它会导致 scanf 读取并丢弃所有空白,直到它看到非空白字符(该字符将保留在输入缓冲区中)。特别是如果您尝试在交互式程序中使用它,它会显示为挂起,直到您输入非空行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不是 scanf("%*[^\n]\n");和 scanf("%*[^\n]%*c");清除悬挂的换行符? 的相关文章

随机推荐

  • 标记 Python 代码中的“print”语句

    我不想在 Python 模块中使用 打印 语句 因为我们将使用记录器 我正在尝试生成一个脚本来使用 pylint 检查模块 但是 pylint 目前不会将此检测为警告或错误 我想根据我们的内部 Python 编程标准将 打印 调用检测为错误
  • Excel Vlookup 返回带有数字的 NA

    我在 Excel 中有一个表格 其中包含 2 列文本和两列数字 这些数字指的是在文本正文中找到搜索字符串的位置 如果没有找到 则单元格留空 例如 ISERROR myfunctions 屏幕截图在这里 我 没有足够的代表来嵌入屏幕截图 我希
  • Oracle“(+)”运算符

    我正在检查一些旧的 SQL 语句 以便记录它们并可能增强它们 DBMS 是 Oracle 我不明白这样的说法 select from a b where a id b id 我很困惑 运算符 并且无法在任何论坛上获取它 在引号内搜索 也不起
  • AppCompatActivity 已弃用 onActivityResult()

    我在用应用内更新适用于 android 和 as根据文档 https developer android com guide playcore in app updates kotlin 他们使用 onActivityResult 来处理应
  • 证明具有 n 个叶子的二叉树的高度至少为 log n

    我已经能够创建一个证明 显示树中的最大总节点数等于 n 2 h 1 1 并且从逻辑上我知道二叉树的高度是 log n 可以绘制它出来看看 但我很难构建一个正式的证明来证明一棵有 n 片叶子的树 至少 有 log n 我遇到或能够组合在一起的
  • WPF 按钮中的文本内容未垂直居中

    WPF 按钮的文本内容在文本上方出现不需要的空格是否有原因 我在 StackPanel 中有一个按钮 这个按钮是一个简单的关闭按钮 所以我希望它显示为一个方形按钮 中间有一个 x 我已将填充设置为零 并将 Horizo ntalConten
  • 如何安装旧版本的 postgresql 和 postgis?

    我是 Linux 新手 我发现安装旧版本的 postgresql 以及 postgis 真的很困难 我已经卸载了在 aptidude 中可以找到的连接到 postgresql 的所有内容 由于只能通过 apt get install 获得最
  • 像 .map() 这样的高阶函数在 JavaScript 内部是如何工作的?

    现在每个人都尝试使用这些高阶函数 https en wikipedia org wiki Higher order function通过编写更少的代码获得有希望的结果 但我想知道这些函数内部是如何工作的 假设我写了类似的东西 var num
  • LibGDX 网格高度图法线和灯光

    我正在尝试让网格法线和灯光在 LibGDX 项目中工作 我已经有了从高度图纹理像素生成的纹理网格 问题是我无法正确点亮法线 另外 我不能 100 确定我在 TerrainChunk 类中正确设置了法线顶点 这是主类代码 package co
  • staggerChildren 与成帧器运动

    我在使成帧器运动 staggerChildren 过渡到处理简单的项目列表时遇到一些问题 它基本上允许子组件的动画交错 我为父容器和子容器设置了这样的动画属性 const container hidden opacity 0 show op
  • ArrayCollection:以表单形式检索集合

    我使用 Symfony2 制作了一个 Web 应用程序 其中用户与实体 Mission 具有数组关联 ManytoMany 用户可以通过表单上传实体 product 表单传递的数据之一是与用户关联的任务 每个用户都有不止一个任务 因此 当他
  • 页脚在底部有CSS网格吗?想不通吗?

    我看过其他教程 了解如何在内容很少时使用 css 网格使页脚粘在底部 但我无法弄清楚 如果你能帮忙 那就太好了 我正在学习 css grid 我花了几天时间断断续续地试图弄清楚它 margin 0 padding 0 color fffff
  • 错误:“文件‘/MasterPages/MainMaster.master’不存在。” (是的,这个文件确实存在!)

    我刚买了一台新的台式电脑 操作系统为 Windows 7 Pro 我在这台新计算机上安装了 Visual Studio 2008 并尝试打开以前存在的 ASP NET 3 5 解决方案 该解决方案在我以前的计算机上显示得非常好 以前的计算机
  • Chrome.system.cpu API 使用情况

    是否可以使用 chrome system cpu api 获取当前 CPU 负载 我特别不知道如何将返回的数字转换为总电流负载的百分比 我发现了这一点 但不太确定如何实现 调用者可以通过进行两次调用 减去时间并除以总时间差来计算负载分数 h
  • 减小折叠菜单的宽度

    在下面的代码中 当单击折叠菜单时 会提供一个与页面全宽的下拉菜单 div class row div class col sm 8 div class navbar header div div div
  • Angular 2 双向数据绑定不起作用

    我在 Angular 2 中获取自定义双向数据绑定时遇到问题 文档表明盒子模型中的香蕉 只是语法糖 但是在我的示例中 这种方式不起作用 而且时间更长方法的工作原理
  • ggplot 中轴/变量标签的键值映射

    我经常使用具有 R 友好 程序员友好 列名称的数据框 通常没有空格和 或缩写 在进行分析时懒于输入全名 例如 ir lt data frame sp iris Species sep len iris Sepal Length sep wi
  • Long 不能取消引用

    我几乎做了一切来解决 长不能取消引用 这个恼人的问题 但一切都解决了 因此 有人可以帮助我吗 问题是当我检查程序是否超时时if System currentTimeMillis longValue finish 比较不起作用 public
  • Sql ServerPreparedStatement为SQL“in(?)”子句设置参数

    我有一个sql看起来像这样 SELECT FROM T TABLE WHERE ID IN 我想设置参数IN via PrepareStatement 我认为所需的方法如下所示 prepareStatement setList 1 Arra
  • 为什么不是 scanf("%*[^\n]\n");和 scanf("%*[^\n]%*c");清除悬挂的换行符?

    拨打电话后scanf d variable 我们留下了一个换行符挂在stdin 应在调用之前清除fgets 或者我们最终给它提供一个换行符并使其过早返回 我找到了建议使用的答案scanf n c 第一次致电后scanf放弃换行符和其他建议使