C 为什么下面的read()代码调用stall?
使用gcc-Wall-W-g3编译时没有收到警告 但是二进制文件没有显示任何内容,也没有得到$prompt。 gcc版本4.9.2(Ubuntu 4.9.2-10ubuntu13)。我是从Keith Haviland的《Unix系统编程》一书中摘取的。read()调用的示例C 为什么下面的read()代码调用stall?,c,gcc,C,Gcc,使用gcc-Wall-W-g3编译时没有收到警告 但是二进制文件没有显示任何内容,也没有得到$prompt。 gcc版本4.9.2(Ubuntu 4.9.2-10ubuntu13)。我是从Keith Haviland的《Unix系统编程》一书中摘取的。read()调用的示例 #包括 #包括 #包括 #包括 #定义BUFSIZE 512 int main() { 字符缓冲区[BUFSIZE]; int-fd; ssize_t nread; 长总计=0; 如果((fd=open(“fi.txt”,O
#包括
#包括
#包括
#包括
#定义BUFSIZE 512
int main()
{
字符缓冲区[BUFSIZE];
int-fd;
ssize_t nread;
长总计=0;
如果((fd=open(“fi.txt”,O_RDONLY)=-1)){
printf(“打开文件时出错\n”);
出口(1);
}
而((nread=read(fd,buffer,BUFSIZE))>0)
总+=nread;
printf(“字符总数:%ld\n”,总计);
出口(0);
}
我不明白gdb显示了什么。fi.txt只包含一个单词,Hello
:
.
(gdb) s
13 if( (fd = open("fi.txt", O_RDONLY) == -1)){
(gdb) s
open () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) print fd
No symbol "fd" in current context.
(gdb) s
0xb7fdbbd0 in __kernel_vsyscall ()
(gdb) s
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
main () at usp5.c:17
17 while( (nread = read(fd, buffer, BUFSIZE))>0)
(gdb) print fd
$1 = 0
(gdb) s
read () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) s
0xb7fdbbd0 in __kernel_vsyscall ()
(gdb) s
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
s
main () at usp5.c:19
19 printf("Total characters: %ld\n", total);
(gdb) print total
$2 = 0
(gdb) print nread
$3 = 2
(gdb) s
__printf (format=0x804863d "Total characters: %ld\n") at printf.c:28
28 printf.c: No such file or directory.
(gdb) print total
No symbol "total" in current context.
(gdb) s
__x86.get_pc_thunk.bx () at ../sysdeps/i386/i686/multiarch/strcat.S:55
55 ../sysdeps/i386/i686/multiarch/strcat.S: No such file or directory.
(gdb) s
__printf (format=0x804863d "Total characters: %ld\n") at printf.c:32
32 printf.c: No such file or directory.
(gdb) s
33 in printf.c
(gdb) list
28 in printf.c
(gdb) s
_IO_vfprintf_internal (s=0xb7fb4e80 <_IO_2_1_stdout_>, format=0x804863d "Total characters: %ld\n",
ap=0xbfffed84 "") at vfprintf.c:222
222 vfprintf.c: No such file or directory.
(gdb) list
......
:
.
(gdb)s
13如果((fd=open(“fi.txt”,Orduonly)=-1)){
(gdb)s
在../sysdeps/unix/syscall template.S:81处打开()
81../sysdeps/unix/syscall template.S:没有这样的文件或目录。
(gdb)打印fd
当前上下文中没有符号“fd”。
(gdb)s
内核vsyscall()中的0xb7fdbbd0
(gdb)s
单步执行,直到退出函数u_kernel_vsyscall,
它没有行号信息。
usp5.c:17的main()
17而((nread=read(fd,buffer,BUFSIZE))>0)
(gdb)打印fd
$1 = 0
(gdb)s
读取../sysdeps/unix/syscall template.S:81处的()
81../sysdeps/unix/syscall template.S:没有这样的文件或目录。
(gdb)s
内核vsyscall()中的0xb7fdbbd0
(gdb)s
单步执行,直到退出函数u_kernel_vsyscall,
它没有行号信息。
s
美国药典5.c版的main():19
19 printf(“总字符数:%ld\n”,总计);
(gdb)打印总数
$2 = 0
(gdb)打印nread
$3 = 2
(gdb)s
__printf处的printf(格式=0x804863d“总字符数:%ld\n”)。c:28
28 printf.c:没有这样的文件或目录。
(gdb)打印总数
当前上下文中没有符号“总计”。
(gdb)s
__x86.get_pc_thunk.bx()位于../sysdeps/i386/i686/multiarch/strcat.S:55
55../sysdeps/i386/i686/multiarch/strcat.S:没有这样的文件或目录。
(gdb)s
__printf处的printf(格式=0x804863d“总字符数:%ld\n”)。c:32
32 printf.c:没有这样的文件或目录。
(gdb)s
打印F.c中的33
(gdb)清单
28英寸打印F.c
(gdb)s
_IO_vfprintf_内部(s=0xb7fb4e80,格式=0x804863d“总字符数:%ld\n”,
在vfprintf.c:222处,ap=0xbffed84“
222 vfprintf.c:没有这样的文件或目录。
(gdb)清单
......
它不停地打印类似的消息。我想你只是犯了一个低级错误: 更改此行代码:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
到
然后你会得到正确的结果
因为您的代码将使fd=0,0是标准输入,所以程序总是等待您的输入。我认为您只是犯了一个低级错误: 更改此行代码:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
到
然后你会得到正确的结果
因为您的代码将使fd=0,并且0是标准输入,所以程序总是等待您的输入。您在这里放错了括号:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
这导致fd被设置为0,而不是open的返回值。因此,实际上您正在从fd0(STDIN)读取数据
应该是:
if( (fd = open("fi.txt", O_RDONLY)) == -1){
您将括号放错了位置:
if( (fd = open("fi.txt", O_RDONLY) == -1)){
这导致fd被设置为0,而不是open的返回值。因此,实际上您正在从fd0(STDIN)读取数据
应该是:
if( (fd = open("fi.txt", O_RDONLY)) == -1){
[评论太长:] 参考最佳实践调试:如果看似简单的代码失败,请查找隐藏的不必要的复杂但重要的结构并将其拆分。在本例中,您展示了两种这样的结构:
if ((fd = open("fi.txt", O_RDONLY) == -1))
{
perror("open() failed");
...
while ((nread = read(fd, buffer, BUFSIZE)) > 0)
这可以写成:
fd = open("fi.txt", O_RDONLY);
if (fd == -1)
{
perror("open() failed");
...
nread = read(fd, buffer, BUFSIZE);
while(nread > 0)
{
...
nread = read(fd, buffer, BUFSIZE);
}
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
if ((fd = open("fi.txt", O_RDONLY) == -1))
{
perror("open() failed");
...
while ((nread = read(fd, buffer, BUFSIZE)) > 0)
报告可以写为:
fd = open("fi.txt", O_RDONLY);
if (fd == -1)
{
perror("open() failed");
...
nread = read(fd, buffer, BUFSIZE);
while(nread > 0)
{
...
nread = read(fd, buffer, BUFSIZE);
}
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
或多个,只需一次调用read()
,但要分离错误处理,这样做的代价是额外的if
:
do
{
nread = read(fd, buffer, BUFSIZE);
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
else
{
...
}
} while (nread > 0);
[评论太长:] 参考最佳实践调试:如果看似简单的代码失败,请查找隐藏的不必要的复杂但重要的结构并将其拆分。在本例中,您展示了两种这样的结构:
if ((fd = open("fi.txt", O_RDONLY) == -1))
{
perror("open() failed");
...
while ((nread = read(fd, buffer, BUFSIZE)) > 0)
这可以写成:
fd = open("fi.txt", O_RDONLY);
if (fd == -1)
{
perror("open() failed");
...
nread = read(fd, buffer, BUFSIZE);
while(nread > 0)
{
...
nread = read(fd, buffer, BUFSIZE);
}
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
if ((fd = open("fi.txt", O_RDONLY) == -1))
{
perror("open() failed");
...
while ((nread = read(fd, buffer, BUFSIZE)) > 0)
报告可以写为:
fd = open("fi.txt", O_RDONLY);
if (fd == -1)
{
perror("open() failed");
...
nread = read(fd, buffer, BUFSIZE);
while(nread > 0)
{
...
nread = read(fd, buffer, BUFSIZE);
}
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
或多个,只需一次调用read()
,但要分离错误处理,这样做的代价是额外的if
:
do
{
nread = read(fd, buffer, BUFSIZE);
if (nread == -1) /* Add as much error checking as possible. */
{
perror("read() failed)");
}
else
{
...
}
} while (nread > 0);
您的
open
conditional中缺少一个正确的表达式参数集..您的open
conditional中缺少一个正确的表达式参数集..非常感谢hermic.现在没事了。一个问题:fi.txt文件包含一个5个字母的单词Hello,但它计数为6。它计数最后一个吗\n?即使是wc-c也显示为6。是的,文件中的所有字符都将被计数,即使是\n。我使用过wc很多次,但我不知道这个功能。我以为wc-c只计算可打印的字符。谢谢。非常感谢hermic。现在没事了。一个问题;文件fi.txt包含一个5个字母的单词Hello,但它计数6。它算上最后一次吗?即使是wc-c节目s 6.是的,文件中的所有字符都将被计数,即使\n.我已经使用wc很多次,但我不知道这个功能。我以为wc-c只计算可打印字符。谢谢。非常感谢Spark Bao。我整晚都在与它搏斗。我犯了一个非常愚蠢的错误。非常抱歉。非常感谢Spark Bao。我一直在与它搏斗彻夜未眠。我犯了一个非常愚蠢的错误。非常抱歉。谢谢你。我已经尝试了你在这里陈述的所有构造。我应该使用peror(),但我怀疑它是否有任何帮助,因为我将括号放在了错误的位置。这个构造中的peror()不起作用;if((fd=open(“fi.txt”,O_RDONLY)=-1)){perror(“open()failed”);…
`但是你的#1的第二部分是正确的