C 为什么下面的read()代码调用stall?

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

使用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_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的第二部分是正确的