如何测试scanf()函数的返回值?

时间:2022-06-02 16:52:54

I want to confirm if a value returned from the scanf() function is a floating number or not. How can I do that? My code is not running as it should if wrong data types are supplied to scanf() function. similarly how would I confirm if a value returned is a character string or not?

我想确认从scanf()函数返回的值是否为浮点数。我怎么做呢?如果向scanf()函数提供了错误的数据类型,我的代码就不能正常运行。类似地,如何确认返回的值是否为字符串?

2 个解决方案

#1


12  

scanf() et al return the number of successful conversions.

scanf()等人返回成功转换的数量。

If you have:

如果你有:

scanf("%f", &f);

you should test:

你应该测试:

if (scanf("%f", &f) == 1)
    ...all OK...
else
    ...EOF or conversion failure...

If you have several conversions, check that they all completed. If you're using %n 'conversions', they aren't counted.

如果您有多个转换,请检查它们是否都已完成。如果您正在使用%n '转换',则不计算它们。

Although scanf() does return EOF on EOF, you should not test for that — you should always check primarily that you got the number of conversions you expected. For example, consider the buggy code:

尽管scanf()在EOF上确实返回EOF,但是您不应该为此进行测试——您应该始终主要检查您所期望的转换的数量。例如,考虑错误代码:

while (scanf("%f %d %s", &f, &i, s) != EOF)  // Here be BUGS!
    ...loop body...

If you type 3.14 x23 yes, then you will have an infinite loop because scanf() will return 1 on the first iteration (it successfully converted 3.14), and 0 thereafter (not EOF).

如果您键入3.14 x23 yes,那么您将会有一个无限循环,因为scanf()将在第一次迭代中返回1(它成功地转换了3.14),然后是0(不是EOF)。

You might be OK with:

你可能会同意:

while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF)
{
    if (rc != 3)
        ...oops data problems...
    else
        ...all OK...
}

Judging from previous questions, you should be looking at using fgets() (or possibly POSIX getline()) to read lines of data, and then using sscanf() or even functions like strtol() and strtod() to read particular values from the line. If you use sscanf(), the comments made above about checking the number of successful conversions still apply.

从前面的问题判断,您应该考虑使用fgets()(或者POSIX getline())来读取数据行,然后使用sscanf(),甚至使用函数strtol()和strtod()从行中读取特定值。如果您使用sscanf(),上面关于检查成功转换的数量的评论仍然适用。

I don't use scanf() in production code; it is just too damn hard to control properly. I regard it as almost suitable for beginning programs — except that it causes lots of confusion. On the whole, the best advice is 'stay clear of scanf() and fscanf()'. Note that that does not mean you have to stay clear of sscanf(), though some caution is needed even with sscanf().

我不会在产品代码中使用scanf();这真是太难控制了。我认为它几乎适用于开始程序——除了它会引起很多混乱。总的来说,最好的建议是“远离scanf()和fscanf()”。注意,这并不意味着您必须远离sscanf(),尽管即使使用sscanf()也需要一定的谨慎。

#2


5  

The return value of scanf indicates the number of items successfully read and assigned to your variables, or EOF:

scanf的返回值表示已成功读取并分配给变量的项的数量,或EOF:

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

这些函数返回成功匹配和分配的输入项的数量,这比在早期匹配失败时提供的要少,甚至是零。

The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.

如果在第一次成功转换或匹配失败发生之前到达输入的末端,则返回值EOF。如果发生读取错误,也将返回EOF,在这种情况下,将设置流的错误指示符(参见ferror(3)),并设置errno表示错误。

If the int returned by scanf has a value less than the amount of input specifiers (or at least the specifiers which require an argument to be passed) in the format string, then you can assume something went wrong.

如果scanf返回的int值小于格式字符串中输入说明符的数量(或者至少是需要传递参数的说明符),那么您可以假定出了问题。

However, if you want to perform a more thorough validation of your floating point number, then you should consider using strtod(). ie. for the input "1.23abc", scanf would store 1.23 into your variable and tell you that everything went well, but with strtod you can check if the last character converted is actually the end of the string being parsed.

但是,如果您想对浮点数进行更彻底的验证,那么应该考虑使用strtod()。ie。对于输入“1.23abc”,scanf将把1.23存储到变量中,并告诉您一切都进行得很好,但是对于strtod,您可以检查转换的最后一个字符是否实际上是正在解析的字符串的末尾。

#1


12  

scanf() et al return the number of successful conversions.

scanf()等人返回成功转换的数量。

If you have:

如果你有:

scanf("%f", &f);

you should test:

你应该测试:

if (scanf("%f", &f) == 1)
    ...all OK...
else
    ...EOF or conversion failure...

If you have several conversions, check that they all completed. If you're using %n 'conversions', they aren't counted.

如果您有多个转换,请检查它们是否都已完成。如果您正在使用%n '转换',则不计算它们。

Although scanf() does return EOF on EOF, you should not test for that — you should always check primarily that you got the number of conversions you expected. For example, consider the buggy code:

尽管scanf()在EOF上确实返回EOF,但是您不应该为此进行测试——您应该始终主要检查您所期望的转换的数量。例如,考虑错误代码:

while (scanf("%f %d %s", &f, &i, s) != EOF)  // Here be BUGS!
    ...loop body...

If you type 3.14 x23 yes, then you will have an infinite loop because scanf() will return 1 on the first iteration (it successfully converted 3.14), and 0 thereafter (not EOF).

如果您键入3.14 x23 yes,那么您将会有一个无限循环,因为scanf()将在第一次迭代中返回1(它成功地转换了3.14),然后是0(不是EOF)。

You might be OK with:

你可能会同意:

while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF)
{
    if (rc != 3)
        ...oops data problems...
    else
        ...all OK...
}

Judging from previous questions, you should be looking at using fgets() (or possibly POSIX getline()) to read lines of data, and then using sscanf() or even functions like strtol() and strtod() to read particular values from the line. If you use sscanf(), the comments made above about checking the number of successful conversions still apply.

从前面的问题判断,您应该考虑使用fgets()(或者POSIX getline())来读取数据行,然后使用sscanf(),甚至使用函数strtol()和strtod()从行中读取特定值。如果您使用sscanf(),上面关于检查成功转换的数量的评论仍然适用。

I don't use scanf() in production code; it is just too damn hard to control properly. I regard it as almost suitable for beginning programs — except that it causes lots of confusion. On the whole, the best advice is 'stay clear of scanf() and fscanf()'. Note that that does not mean you have to stay clear of sscanf(), though some caution is needed even with sscanf().

我不会在产品代码中使用scanf();这真是太难控制了。我认为它几乎适用于开始程序——除了它会引起很多混乱。总的来说,最好的建议是“远离scanf()和fscanf()”。注意,这并不意味着您必须远离sscanf(),尽管即使使用sscanf()也需要一定的谨慎。

#2


5  

The return value of scanf indicates the number of items successfully read and assigned to your variables, or EOF:

scanf的返回值表示已成功读取并分配给变量的项的数量,或EOF:

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

这些函数返回成功匹配和分配的输入项的数量,这比在早期匹配失败时提供的要少,甚至是零。

The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.

如果在第一次成功转换或匹配失败发生之前到达输入的末端,则返回值EOF。如果发生读取错误,也将返回EOF,在这种情况下,将设置流的错误指示符(参见ferror(3)),并设置errno表示错误。

If the int returned by scanf has a value less than the amount of input specifiers (or at least the specifiers which require an argument to be passed) in the format string, then you can assume something went wrong.

如果scanf返回的int值小于格式字符串中输入说明符的数量(或者至少是需要传递参数的说明符),那么您可以假定出了问题。

However, if you want to perform a more thorough validation of your floating point number, then you should consider using strtod(). ie. for the input "1.23abc", scanf would store 1.23 into your variable and tell you that everything went well, but with strtod you can check if the last character converted is actually the end of the string being parsed.

但是,如果您想对浮点数进行更彻底的验证,那么应该考虑使用strtod()。ie。对于输入“1.23abc”,scanf将把1.23存储到变量中,并告诉您一切都进行得很好,但是对于strtod,您可以检查转换的最后一个字符是否实际上是正在解析的字符串的末尾。