我一直有一个很大的问题,试图找出如何使用scanf()
。 这似乎很好地工作整数,是相当直截了当scanf("%d", &i)
当我遇到问题时使用scanf()
在循环试图读取输入。 例如:
do {
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
当我像一个有效的结构输入输入c P101
,它似乎促使我之前再次循环。 这似乎与一个甚至发生:
scanf("%c", &c)
在一个while循环。 再次提示我之前它会做循环两次。 是什么使得它循环两次,我该如何阻止它?
当我在编程不会有另一个字符或数字,如输入量少进入q
,按enter似乎提示我输入更多。 如何获得scanf()
来处理单,双字条目?
当你进入“ c P101
”节目实际收到“ c P101\n
”。 大部分的转换说明跳过前导空白包括换行,但%c
没有。 周围的一切了无菌的“第一次\n
”被读取时,第二次围绕“\ n”被读入command
,“ c
”被读入prefix
,和“ P
”被留下这不是一个号码,以便在转换失败和“ P101\n
”被留在流。 下一次“ P
”被存储到命令,“ 1
”被存储到前缀,以及1
(从剩余的“ 01
‘)被存储到输入用’ \n
”仍然在流为下一次。 您可以通过在格式字符串,这将跳过任何前导空格,包括换行的开头放一个空间解决此问题。
一个类似的事情也发生第二种情况,当你输入“ q
”,“ q\n
”输入到流,围绕“首次q
”被读取时,第二次“ \n
”被读取,仅在第三个电话是继“ q
”阅读,您可以通过在格式字符串的开头添加一个空格字符再次避免此问题。
一个更好的办法来做到这一点是使用类似与fgets()来处理在一个时间线,然后使用的sscanf()做解析。
这真的碎了! 我不知道它
#include <stdio.h>
int main(void)
{
int counter = 1;
char command, prefix;
int input;
do
{
printf("counter: %d: ", counter);
scanf("%c %c%d", &command, &prefix, &input);
printf("---%c %c%d---\n", command, prefix, input);
counter++;
} while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
g3---
输出似乎适合与罗伯特的回答。
一旦你有一个包含行的字符串。 即“C P101”,你可以使用的sscanf的解析能力。
请参阅: http://www.cplusplus.com/reference/clibrary/cstdio/sscanf.html
问题1,我怀疑你有你的问题printf()
因为没有终止“\ n”。
的默认行为printf
是缓冲输出,直到它有一个完整的线。 也就是说,除非你明确地改变缓冲stdout
。
对于问题2,你刚才打的有一个最大的问题scanf()
。 除非你输入你所指定的扫描字符串完全匹配,你的结果将是没有像你期望的。
如果你有一个选项,你就必须通过忽略更好的结果(和更少的安全问题) scanf()
,做你自己的分析。 例如,使用fgets()
来读取整个行成一个字符串,然后处理该字符串的各个字段-甚至使用sscanf()
或许用while循环,而不是一个do ... while循环会有所帮助。 这样的条件是代码的执行之前进行测试。 试试下面的代码片段:
while(command != 'q')
{
//statements
}
另外,如果你事先知道字符串的长度,“为”循环可以更容易比“而”循环工作。 也有一些棘手的方式来动态地确定长度为好。
作为最后的咆哮: scanf()
没有“吸”。 它做它做什么,这是所有。 fgets()
是非常危险的(虽然方便了无风险的应用程序),因为它本身并不做任何输入检查。 这是非常俗称利用一个点,特别缓冲区溢出攻击,在不分配给该变量寄存器覆盖空间。 因此,如果您选择使用它,花一些时间把一些固定误差检测/校正英寸
希望这可以帮助别人的未来,因为我相信你已经得到它现在处理! ;)