c - 将空文件重定向为 C 中的输入

标签 c io

我正在阅读有关将输入文件重定向到 C 程序的内容,并在试验代码和使用空文件“inp”时遇到以下内容:

#include <stdio.h>
int main()
{
    int i=10;
    scanf("%d", &i);
    printf("%d", i);
    return 0;
}

输出:

$ ./a.out < inp
10

我无法理解为什么 scanf() 不停止程序读取输入,尽管重定向的文件是空的,但它会跳到 printf() 函数。

此外,当我修改代码以包含未初始化的 i 时:

#include <stdio.h>
int main()
{
    int i;
    scanf("%d", &i);
    printf("%d", i);
    return 0;
}

输出:

$ ./a.out < inp
0

它总是打印 0,但是根据上面的行为,它不应该打印未初始化的 i 中已经存在的垃圾值吗?

最佳答案

scanf() 不会在空输入时失败,但只是不执行任何操作。您可能想要检查返回值,如下所述:

man fscanf

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.

关于未初始化的 i:这是一个隐式初始化,值为 0。有人称其为特性。

但是,如果您没有使用 scanf(),编译器会警告您:

#include <stdio.h>
int main()
{
    int i, j;
    scanf("%d", &i);
    printf("%d / %d\n", i, j);
    return 0;
}

启用所有警告的编译:

$ cc -Wall -Wextra -Wpedantic test.c -o test
test.c: In function 'main':
test.c:6:11: warning: 'j' is used uninitialized in this function [-Wuninitialized]
     printf("%d / %d\n", i, j);
           ^

运行程序

 $ ./test < empty_file
0 / 0

你看,即使 j 也打印出零。


我添加了另一个测试:

在scanf之后添加:

    int k = i;
    int l = j;

    printf("%d / %d\n", k, l);

结果:

 $ ./test < empty_file 
 1115201808 / 0

所以,当我运行 scanf 时,j 完全未初始化。
结果可以随意重现,k 始终是随机的,l 始终为零。

关于c - 将空文件重定向为 C 中的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26100044/

相关文章:

c++ - 如何修改按值传递的原始变量的内容?

创建一个新字符串,该字符串将由其他两个字符串中的常见字母组成

function - 关于 Haskell IO Monad 中的(执行时)

go - bufio.NewScanner(r) 从 r 调用 Scan() 排出缓冲区

c - 如何关闭 write() 系统调用的缓冲?

java - 使用 java.nio 写入文件

C - 不使用 strcmp() 按字母顺序对字符串进行排序

c - 如何检查C中未初始化的指针

c - malloc 和 free 的不同行为?

ruby - 观看/阅读不断增长的日志文件