2016-09-27 4 views
0

Keine Warnung Kompilierung mit gcc -Wall -W -g3 < inputfile.c> aber binary zeigt nichts und nicht bekommen $ prompt. gcc Version 4.9.2 (Ubuntu 4.9.2-10ubuntu13). Ich habe es aus dem Buch Unix System Programming von Keith Haviland genommen. Beispiel für den Aufruf von read().Warum stört der folgende Code von read()?

#include<stdio.h> 
    #include<stdlib.h> 
    #include<fcntl.h> 
    #include<unistd.h> 
    #define BUFSIZE 512 
    int main() 
    { 
    char buffer[BUFSIZE]; 
    int fd; 
    ssize_t nread; 
    long total = 0; 

    if((fd = open("fi.txt", O_RDONLY) == -1)){ 
     printf("error in opening file\n"); 
     exit(1); 
     } 
    while((nread = read(fd, buffer, BUFSIZE))>0) 
    total += nread; 
    printf("Total characters: %ld\n", total); 
    exit(0); 
} 

Ich kann nicht verstehen, was gdb zeigt. fi.txt enthält nur ein Wort, Hallo.

: 
. 
(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 
...... 

Es geht weiter und auf dem Drucken ähnlicher Nachrichten.

+0

Du bist Es fehlt ein richtiger Ausdrucks-Parameter, der in Ihrer 'offenen' Bedingung gesetzt ist. [Ein ** genaues ** Duplikat dieser Frage] (http://stackoverflow.com/questions/13169693/file-descriptors-open-returns-zero). – WhozCraig

Antwort

1

Ich glaube, Sie nur einen geringen Fehler machen:

Änderung dieser Zeile Code:

if((fd = open("fi.txt", O_RDONLY) == -1)){ 

zu

if((fd = open("fi.txt", O_RDONLY)) == -1){ 

dann werden Sie richtiges Ergebnis bekommen.

weil Ihr Code wird fd = 0, und 0 ist die stdin, so dass die progrm immer Ihre Eingabe warten.

+0

Vielen Dank Spark Bao. Ich habe die ganze Nacht damit gerungen. Ich habe einen sehr dummen Fehler begangen. So leid. – Bishnu

3

Sie haben hier fehl am Platze Klammern:

if((fd = open("fi.txt", O_RDONLY) == -1)){ 

, die in fd-Ergebnisse auf 0 gesetzt wird, anstatt den Rückgabewert offen. Sie lesen also tatsächlich von fd 0 (STDIN).

es sein sollte:

if((fd = open("fi.txt", O_RDONLY)) == -1){ 
+0

Vielen Dank hermic. Jetzt ist es ok. Eine Frage; Die Datei fi.txt enthält ein 5-stelliges Wort Hallo aber es zählt 6. Zählt es die letzte \ n? Sogar wc -c zeigt 6. – Bishnu

+0

Ja, alle Zeichen in der Datei werden gezählt, auch \ n. – harmic

+0

Ich habe viele Male WC benutzt, aber ich war mir dieser Funktion nicht bewusst. Ich dachte, wc -c zählt nur druckbare Zeichen. Vielen Dank. – Bishnu

0

[zu lang für einen Kommentar:]

best practice-Debugging Mit Bezug: Wenn scheinbar einfacher Code fehlschlägt, suchen Sie nach versteckten unnötig komplex, aber wesentlichen Konstrukten und nehmen sie auseinander .Im Fall, dass Sie es zeigen, sind zwei solche Konstrukte:

  1. Öffnen der Datei:

    if ((fd = open("fi.txt", O_RDONLY) == -1)) 
        { 
        perror("open() failed"); 
        ... 
    

    Dieses geschrieben werden könnte:

    fd = open("fi.txt", O_RDONLY); 
        if (fd == -1) 
        { 
        perror("open() failed"); 
        ... 
    
  2. aus der Datei lesen:

    while ((nread = read(fd, buffer, BUFSIZE)) > 0) 
    

    Die könnte geschrieben werden:

    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)"); 
        } 
    

    oder mehr mit nur ein Aufruf read(), aber Fehlerbehandlung, für die Kosten eines zusätzlichen if auf diese Weise zu trennen:

    do 
    { 
        nread = read(fd, buffer, BUFSIZE); 
        if (nread == -1) /* Add as much error checking as possible. */ 
        { 
        perror("read() failed)"); 
        } 
        else 
        { 
        ... 
        } 
    } while (nread > 0); 
    
+0

Danke alk. Ich habe mit allen Konstrukten versucht, die Sie hier angegeben haben. Ich hätte perror() verwenden sollen, aber ich bezweifle, dass es eine Hilfe sein könnte, da ich die Klammern in eine falsche Position gebracht habe. perror() in diesem Konstrukt funktioniert nicht; 'if ((fd = offen (" fi.txt ", O_RDONLY) == -1)) { perror (" open() fehlgeschlagen "); ... '' aber zweiter Teil Ihrer # 1 ist in Ordnung. – Bishnu

+0

Erster Teil Ihrer # 2 Ich fügte eine Zeile als 'nread = lesen (fd, Puffer, BUFSIZE); ** gesamt = nadeln; ** while (nadeln> 0) { ... ' dann funktioniert es. Könnten Sie mir bitte sagen, wie ich ** nread ** scheitern könnte, damit ich Ihre # 2 Beispiele testen kann? – Bishnu

+0

Entschuldigung für die Formatierung. – Bishnu

Verwandte Themen