我对以下代码感到困惑,
#include<stdio.h>
int main()
{
char buf[100]={'\0'};
int data=0;
scanf("%d",&data);
read(stdin,buf,4); //attaching to stdin
printf("buffer is %s\n",buf);
return 1;
}
假设在运行时我提供了输入10abcd
,因此根据我的理解,应该会发生以下情况:
10
放入数据abcd
仍将在stdin缓冲区abcd
已存在),应将abcd
放入buf
abcd
但它没有发生,printf显示没有o / p
我在这里错过了什么吗?答案 0 :(得分:4)
首先read (stdin, ...)
应该发出警告(如果你启用了它们),你应该明智地注意这些警告。 read()
使用整数作为指定要从中读取哪个通道的第一个参数。 stdin
的类型为FILE *
。
即使您将其更改为read(0,...
,也不建议这样做。 scanf
正在从FILE *stdin
读取,它从文件句柄0缓冲。read (0, ...)
直接从基础文件句柄读取并忽略任何缓冲的字符。除非stdin
设置为无缓冲,否则这将导致奇怪的结果。
答案 1 :(得分:3)
忽略与read()
函数调用语法相关的机械问题,有两种情况需要考虑:
在用户返回之前,没有数据可供阅读。此时,标准I / O库将所有可用数据读入与stdin
相关联的缓冲区(即“10abcd \ n”)。然后它将解析数字,将a
留在缓冲区中,稍后由其他标准I / O函数读取。
当read()
发生时,它也会等待用户提供一些输入。它对stdin
缓冲区中的数据一无所知。它将一直挂起,直到用户返回,然后将读取下一批数据,在缓冲区中返回最多4个字节(没有空终止,除非第四个字符是ASCII NUL '\0'
)。
实际上,这并没有太大的不同,除了不是将一行数据读入缓冲区,标准I / O库可能会读取整个缓冲区,(BUFSIZ
字节,可能是512或更大)。然后它会转换10
并离开a
以供日后使用。 (如果文件短于缓冲区大小,则将全部读入stdin
缓冲区。)
然后read
将从文件中收集接下来的4个字节。如果已经读取了整个文件,则它将不返回任何内容 - 读取0个字节。
您需要记录并检查read()
的返回值。您还应该检查scanf()
的返回值,以确保它确实读取了一个数字。
答案 2 :(得分:1)
首先尝试... man read
。
read声明为ssize_t read(int fd,void * buf,size_t count);
和stdin被声明为FILE *。这就是问题所在。改为使用fread(),你将被排序。
int main()
{
char buf[100]={'\0'};
int data=0;
scanf("%d",&data);
fread(buf, 1, 4, stdin);
printf("buffer is %s\n",buf);
return 1;
}
编辑:您的理解几乎是正确的,但并非完全正确。 为了正确解决您的问题,我同意Jonathen Laffer。
您的代码如何运作,
1)scanf应在数据中放置10个。
2)按ENTER键时,abcd仍然在stdin缓冲区上。
3)然后read()将再次等待输入,你必须再次按ENTER进一步运行程序。
4)现在,如果您在第二次按ENTER之前输入了任何内容,则printf应该打印出来,否则除了printf语句之外,您将无法获得任何输出。
这就是为什么我要求你使用fread。希望它有所帮助。