c语言中的行输入
如何在c中强制执行以下输入限制 第一行包含float, 第二行包含float, 第三行int 在控制台中按enter三次后,程序应该能够读取每一行,并将内容放入相应的int、int、float变量中 三次输入后,按键程序不应等待用户输入并开始验证 一些测试用例c语言中的行输入,c,validation,input,scanf,C,Validation,Input,Scanf,如何在c中强制执行以下输入限制 第一行包含float, 第二行包含float, 第三行int 在控制台中按enter三次后,程序应该能够读取每一行,并将内容放入相应的int、int、float变量中 三次输入后,按键程序不应等待用户输入并开始验证 一些测试用例 line1: 34 line2:4 line3:12 result: ok line1: line2:4 line3:12 result: not ok line1: Hi line2:4 line3:12 result: no
line1: 34
line2:4
line3:12
result: ok
line1:
line2:4
line3:12
result: not ok
line1: Hi
line2:4
line3:12
result: not ok
到目前为止,我使用的是基础知识
scanf("%f",&p);
scanf("%f",&r);
scanf("%d",&t);
对于测试用例1和3,它工作得很好,但当我留下一个空行时,它就失败了 您应该始终检查
scanf
的返回值
原因是返回值是scanf
用于传达转换错误和其他错误的值。例如,如果您的程序告诉scanf
需要一个十进制数字序列,并且scanf
遇到与该模式不匹配的内容,则返回值将指示此故障
返回的值将是成功分配给的项目数。比如说,
char str[128];
int x, y = scanf("%d %127s", &x, str);
如果y
为1,则应假定x
可以安全使用。如果y
为2,则应假定x
和str
都可以安全使用
这部分回答了你的问题。下一部分是如何确保输入是以行的形式进行的scanf
不严格处理行;它处理其他单位,例如%d
作为int
编码为十进制数字序列(和符号);它将在十进制数字序列结束后返回。。。不能保证小数位数会占据整行
这里实际上有两个问题:前导空格和尾随空格。除了[
、c
、c
和n
之外,所有格式说明符都将导致前导空格被丢弃。如果您希望以不同的方式处理前导空格,则需要对预期的前导空格处理方式进行编码
考虑到丢弃用户输入几乎总是(如果不是总是)一个坏主意。如果您不关心行的其余部分包含什么,可以使用类似于scanf(“%*[^\n]”;getchar()的内容;
要放弃所有跟在'\n'
换行符后面的字符,第一条语句将尝试读取尽可能多的非换行符,第二条语句将放弃终止的换行符。但是,如果要确保输入占用整行,则需要o测试getchar
返回的值
使用所有这些注意事项的示例:
/* Test for leading whitespace (including newlines) */
int c = getchar();
if (c != '-' && !isdigit(c)) {
/* Leading whitespace found */
}
ungetc(c);
/* Test for correct data conversion */
int x, y = scanf("%d", &x);
if (y != 1) {
/* Something non-numeric was entered */
}
/* Test for trailing newline */
c = getchar();
if (c != '\n') {
/* Trailing newline found */
}
有了这些信息,如果您有任何问题,也许您可以尝试用一些代码更新您的问题
另外,我注意到在你写的代码中,你似乎把%f
和%d
搞混了;%f
是用来读入浮点数的,%d
是用来读入int
S的,而不是反过来……只要我读入行输入,我就知道fgets
+/code>+必须是使用而不是直接scanf
。当然,您可以使用getc
/getchar
作为解决方法,但您可以使用角盒,我发现fgets
+sscanf
更干净。在一行上单独使用浮点的示例:
char line[80], dummy[2];
float val;
if (fgets(line, sizeof(line), stdin) == NULL)...
if (sscanf(line, "%f%1s", &val, dummy) != 1)...
// Ok val was alone on the line with optional ignored blanks before and/or after
您还可以为Looong线添加测试:
if ((line[0] != 0) && (line[strlen(line)-1 != '\n'))...
是否必须使用scanf
执行此操作?使用fgets
读取行。使用sscanf
或strto\ucode>函数系列进行转换。我不允许仅使用conio.h.stdio.h:(fgets
->trim->sscanf
with%n
这些函数都不在其中。fgets
和sscanf
在中。strto
在中如何比float val;int n=scanf(“%f”,&val);scanf(“%*[^\n]”;getchar();if(n!=1){/}一些错误处理*}
?添加长行测试会给您的代码增加比您可能意识到的更多的混乱。您需要考虑当fgets
遇到长度超过sizeof(line)
字符的行时,例如…您可以使用scanf(“%*[^\n]”);getchar();
,但是你会使用scanf
…这太傻了,对吧?为什么要为这项工作使用最合适的工具呢?@Freenode newbostonesbivor你的代码确实要短得多…并且在同一行默默地接受OP禁止的3个浮点数。如果你不需要面向行的输入,fgets
,那就太过分了。但是如果您需要它,这是一种更健壮的方法。该代码不会“在同一行上静默地接受3个浮点”…int n=scanf(“%f”,&val);
将一个值读入val
,然后scanf(“%*[^\n]”;getchar();
将丢弃输入行的剩余部分,这是单独使用fgets
+sscanf
无法干净可靠地完成的,因为当一行长度超过sizeof(行)时
它会将行拆分为两次读取。在这种情况下,你可以使用我用来丢弃行剩余部分的相同代码,但你也可以使用scanf
而不是fgets
+sscanf
getchar
来完成这一切,代价是混乱。有一件事我不明白,而且也就是说,“fgets
+sscanf
在使用scanf
+getchar
时不存在问题,fgets
被认为“更健壮”?fgets+sscanf
忽略前导空格或尾随空格(可以是空格、制表符或\r
)并拒绝empy行,因为每行只要求一个值。使用scanf+getchar
,程序员必须明确地处理空格或制表符