2013-03-31 9 views
5

Wie überprüft man, ob ein Zeichen ein Newline-Zeichen in einer Codierung in C ist?Überprüfen eines Zeichens als Newline

Ich habe eine Aufgabe, meine eigene wc Programm zu schreiben. Und wenn ich nur wenn (s[i] == '\n') verwenden, hat es eine andere Antwort als Original wc wenn ich es zu sich selbst rufe.
Hier ist der Code:

typedef struct 
{ 
    int newline; 
    int word; 
    int byte; 
} info; 

info count(int descr) 
{ 
    info kol; 
    kol.newline = 0; 
    kol.word = 0; 
    kol.byte = 0; 

    int len = 512; 
    char s[512]; 
    int n; 

    errno = 0; 
    int flag1 = 1; 
    int flag2 = 1; 
    while(n = read(descr, s, len)) 
    { 
     if(n == -1) 
      error("Error while reading.", errno); 

     errno = 0; 

     kol.byte+=n; 
     for(int i=0; i<n; i++) 
     { 
      if(flag1) 
      { 
       kol.newline++; 
       flag1 = 0; 
      } 

      if(isblank(s[i]) || s[i] == '\n') 
       flag2 = 1; 
      else 
      { 
       if(flag2) 
       { 
        kol.word++; 
        flag2 = 0; 
       } 
      } 
      if(s[i] == '\n') 
       flag1 = 1; 
     } 
    } 
    return kol; 
} 

Es funktioniert für alle Textdateien in Ordnung, aber wenn ich es nenne ich nach dem Kompilieren selbst does Datei habe es wc gibt die Antwort geben.

+1

Sie meinen wie ''\ n''? – Useless

+0

'\ n' funktioniert nur in ASCII-Codierung. ich meine so etwas wie _isdigit() _ function – Taygrim

+0

Sie nennen 'read (descr)', wobei 'descr 'vermutlich ein Dateideskriptor ist. Wie wurde es geöffnet? Und * wie * unterscheidet sich Ihre Ausgabe von der von 'wc', und von welcher Eingabe? –

Antwort

5

Die Art zu prüfen, ob ein Zeichen s[i] ein Zeilenumbruchzeichen ist, lautet einfach:

if (s[i] == '\n') 

Wenn Sie aus einer Datei gerade lesen, die (einschließlich stdin) im Textmodus geöffnet worden sind, dann was auch immer Darstellung des zugrundeliegende System verwendet das Ende einer Zeile zu markieren, wird zu einem einzigen '\n' Zeichen übersetzt werden.

Sie sagen, Sie versuchen, Ihre eigenen wc Programm zu schreiben, und durch den Vergleich mit '\n' erhalten Sie andere Ergebnisse als das System wc. Du hast uns nicht genug erzählt, um zu wissen, warum das passiert. Zeigen Sie uns Ihren Code und teilen Sie uns genau mit, was gerade passiert.

Es kann zu Problemen kommen, wenn Sie eine Datei lesen, die anders codiert ist - zB wenn Sie versuchen, eine Unix-Textdatei auf einem Windows-System zu lesen. Aber dann hätte wc das gleiche Problem.

2

Es gibt mehrere Zeilenvorschubzeichen in ASCII und Unicode. Die bekanntesten sind \r und \n, aus ASCII. Technisch sind dies Wagenrücklauf und Zeilenvorschub. Windows verwendet beide zusammen \r\n (technisch Carriage-Return bedeutet, gehen Sie in die Spalte 0, Zeilenvorschub bedeutet, gehen Sie zur nächsten Zeile, aber nichts, was ich weiß, gehorcht, dass in der Praxis) verwendet nur \n. Einige (nicht gebräuchliche) Betriebssysteme verwenden nur \r.

Die meisten Apps stoppen dort und leiden nicht dafür. Was folgt, ist eher theoretisch.

Unicode kompliziert die Dinge. U + 000A und U + 000B sind identisch mit \r und \n (gleiche binäre Darstellung in UTF-8). Dann gibt es U + 0085 "nächste Zeile", U + 2028 "Zeilentrennzeichen" und U + 2029 "Absatztrennzeichen". Sie können auch die vertikale Registerkarte (U + 000B) überprüfen, wenn Sie alles überprüfen möchten. Siehe hier: http://en.wikipedia.org/wiki/Newline#Unicode

+0

In früheren Zeiten brauchten einige Schreibmaschinen beide Wagenrücklauf * und * Zeilenvorschub. –

+0

@xtofpernaud ich weiß, es gab einen Trick mit sehr alten Druckern, um sie Zeichen zu überdrucken, um Bilder zu zeichnen, aber ich meinte wirklich alles, was immer noch ist allgemein verwendet! – Dave

+0

\ r \ n wird immer noch verwendet, zum Beispiel verwenden alle zeilenbasierten Protokolle (z. B. SMTP, IMAP, POP3) und andere (z. B. HTTP-Header) \ r \ n als Zeilenende. Und auch, wenn Sie Daten an ein Terminal auf niedriger Ebene senden, bin ich mir ziemlich sicher, dass das \ r immer noch in Spalte 0 zurückgegeben werden muss. – Ale

1

Soweit ich weiß, gibt es keine Standardfunktion wie die isXXXXX() diejenigen (die meisten in der Nähe ist isspace(), die auch für andere Bedingungen (Leerzeichen, Tabulator, Formularvorschub ... wahr ist). Einfaches Vergleichen mit '\ n' sollte Ihr Problem lösen, je nachdem, was Sie als Newline-Zeichen betrachten, sollten Sie auch nach '\ r' (Wagenrücklauf) suchen. Der UNIX-Standard als Zeilentrenner ist '\ n', Mac (vor OS X) verwendet '\ r' (jetzt ist '\ n' häufiger, aber '\ r' wird manchmal noch von einigen Anwendungen verwendet, zB MS Office), DOS/Windows benutzen das "\ r \ n"

+0

Mac OS X verwendet '\ n' und nicht' \ r'. –

+0

Nicht in allen Anwendungen (siehe zum Beispiel CSV-Dateien exportiert von Excel auf OS X) – Ale

+0

@Ale das ist wahrscheinlich mehr, weil Microsoft nicht bemerkt hat, dass es sich im Update geändert hat ... im Allgemeinen ist es '\ n' jetzt, aber es tut nicht ' t wichtig, weil Sie immer auf * alles * überprüfen sollten. Sie wissen nie, wann ein Benutzer eine Datei von einem anderen Betriebssystem kopiert hat. – Dave

Verwandte Themen