c语言中的行输入

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

如何在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:  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
,程序员必须明确地处理空格或制表符