Prüfen, ob ein Zeichen ein Zeilenumbruch ist

Lesezeit: 6 Minuten

Benutzeravatar von Taygrim
Taygrim

Wie kann ich überprüfen, ob ein Zeichen in einer Codierung in C ein Zeilenumbruchzeichen ist?

Ich habe eine Aufgabe, meine eigene zu schreiben Toilette Programm. Und wenn ich nur if benutze (s[i] == '\n') es hat eine andere Antwort als das Original Toilette wenn ich es zu mir 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 gut für alle Textdateien, aber wenn ich es in eine Datei aufrufe, die ich nach dem Kompilieren erhalten habe, gibt es keine Antwort Toilette gibt.

  • Du meinst wie '\n'?

    – Nicht zu gebrauchen

    31. März 2013 um 19:41 Uhr

  • ‘\n’ funktioniert nur in ASCII-Kodierung. Ich meine so etwas wie isdigit() Funktion

    – Taigrim

    31. März 2013 um 19:42 Uhr

  • Du rufst an read(descr)wo descr ist vermutlich ein Dateideskriptor. Wie wurde es geöffnet? Und wie unterscheidet sich Ihre Ausgabe von der von wcund auf welcher Eingabe?

    – Keith Thompson

    1. April 2013 um 3:09 Uhr

  • descr wird in einem anderen Teil des Programms geöffnet int descr = open(argv[i], 0);. Unterschied: wc: 5 27 2520 count.o my_wc: 6 17 2520 count.o. Bei der Eingabe gebe ich Dies zusammengestellt mit gcc -std=c99 -c -o count.o count.c

    – Taigrim

    1. April 2013 um 6:11 Uhr


  • es sieht so aus, als würden Sie wc in einer Binärdatei aufrufen … da es nicht dafür gemacht ist, bin ich mir nicht sicher, ob es ein aussagekräftiges Ergebnis ausgeben wird. Möglicherweise hängt das Problem mit “unterminierten” Zeilen zusammen (zB wenn die letzte nicht mit einem Zeilenumbruch endet).

    – Ale

    1. April 2013 um 7:59 Uhr


Der Weg, um zu überprüfen, ob ein Zeichen s[i] ist ein Zeilenumbruchzeichen ist einfach:

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

Wenn Sie aus einer Datei lesen, die im Textmodus geöffnet wurde (einschließlich stdin), dann wird jede Darstellung, die das zugrunde liegende System verwendet, um das Ende einer Zeile zu markieren, in eine einzelne übersetzt '\n' Charakter.

Du sagst, du versuchst, deine eigene zu schreiben wc Programm und durch den Vergleich mit '\n' Sie erhalten andere Ergebnisse als das System wc. Sie haben uns nicht genug erzählt, um zu erraten, warum das passiert. Zeigen Sie uns Ihren Code und sagen Sie uns genau, was passiert.

Sie könnten auf Probleme stoßen, wenn Sie eine Datei lesen, die anders kodiert ist – sagen wir, wenn Sie versuchen, eine Textdatei im Unix-Format auf einem Windows-System zu lesen. Aber dann wc hätte das gleiche Problem.

  • C Neuling ist da < es hat 10 Minuten gedauert bis ich das gemerkt habe ‘\n’ ist nicht "\n" 😀

    – Buchhalter م

    3. April 2019 um 0:58 Uhr

  • Dieser Link kann jemandem später helfen. Es geht darum, beim Lesen aus einer Datei keine Leerzeichen zu überspringen.

    – Gabriel Arghire

    9. März 2021 um 15:15 Uhr

  • @JusticeBringer Vielleicht, aber der Link ist spezifisch für C++, nicht für C.

    – Keith Thompson

    9. März 2021 um 19:15 Uhr

  • Stimmt, da hast du nicht drauf geachtet. Trotzdem weißt du nicht, wer das später braucht.

    – Gabriel Arghire

    10. März 2021 um 8:45 Uhr

Es gibt mehrere Zeilenumbruchzeichen in ASCII und Unicode.

Die bekanntesten sind \r und \n, aus ASCII. Technisch gesehen sind dies Wagenrücklauf und Zeilenvorschub. Windows verwendet beide zusammen \r\n (Technisch bedeutet Carriage-Return, gehe zur Spalte 0, Line-Feed bedeutet, gehe zur nächsten Zeile, aber nichts, von dem ich weiß, befolgt das in der Praxis), verwendet Unix just \n. Einige (nicht übliche) Betriebssysteme verwenden nur \r.

Die meisten Apps hören dort auf und leiden nicht darunter. Was folgt, ist eher theoretisch.

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

  • @xtofpernaud Nun, ich weiß, dass es bei sehr alten Druckern einen Trick gab, damit sie Zeichen überdrucken, um Bilder zu zeichnen, aber ich bezog mich wirklich auf alles, was immer noch allgemein verwendet wird!

    – David

    31. März 2013 um 19:58 Uhr

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

    – Ale

    31. März 2013 um 20:15 Uhr

  • Wenn Sie im Textmodus lesen, müssen Sie sich um nichts weiter kümmern als '\n'. Unabhängig davon, welche Darstellung das Betriebssystem verwendet, wird übersetzt.

    – Keith Thompson

    31. März 2013 um 20:15 Uhr

  • @Ale: Das Terminal ist interessant; klingelt, um Fortschrittsbalken zu erstellen. HTTP hat keine Möglichkeit, a zu behandeln \r oder \n allein, so dass es sich wie Fenster verhält, anstatt der wörtlichen Bedeutung der Zeichen zu gehorchen.

    – David

    31. März 2013 um 20:20 Uhr

  • @KeithThompson: Der Textmodus normalisiert nicht unbedingt alles. Es kann auch dazu führen, dass EOF-Zeichen das wörtliche Dateiende verursachen, also ist es nicht immer das Beste, was zu verwenden ist (persönlich bevorzuge ich es, Zeilenenden selbst zu handhaben).

    – David

    31. März 2013 um 20:22 Uhr

Benutzeravatar von Ale
Ale

Soweit ich weiß, gibt es keine Standardfunktion wie die isXXXXX() diejenigen (am nächsten ist isspace(), was auch für andere Bedingungen gilt (Leerzeichen, Tabulator, Formularvorschub …). Ein einfacher Vergleich mit ‘\n’ sollte Ihr Problem lösen; Abhängig davon, was Sie als Zeilenumbruchzeichen betrachten, möchten Sie vielleicht auch nach ‘\r’ (Wagenrücklauf) suchen. UNIX-Standard als Zeilentrenner ist ‘\n’, Mac (vor OS X) verwendet ‘\r’ (jetzt ist ‘\n’ gebräuchlicher, aber ‘\r’ wird manchmal noch von einigen Anwendungen verwendet, z. B. MS Office), DOS/Windows verwenden die Sequenz “\r\n”.

  • Mac OS X verwendet \n und nicht \r.

    – Jonathan Leffler

    31. März 2013 um 19:54 Uhr

  • Nicht in allen Anwendungen (siehe zum Beispiel CSV-Dateien, die von Excel unter OS X exportiert wurden)

    – Ale

    31. März 2013 um 20:00 Uhr

  • @Ale das liegt wahrscheinlich eher daran, dass Microsoft nicht bemerkt hat, dass es sich im Update geändert hat … im Allgemeinen ist es so \n jetzt, aber es spielt keine Rolle, weil Sie immer überprüfen sollten irgendetwas. Sie wissen nie, wann ein Benutzer eine Datei von einem anderen Betriebssystem kopiert hat.

    – David

    31. März 2013 um 20:02 Uhr

  • Richtig, MS hat nicht bemerkt, dass OS X jetzt vielleicht UNIX-basiert ist 😉 Ich habe meine Antwort präzisiert.

    – Ale

    31. März 2013 um 20:04 Uhr

  • Wenn Sie im Textmodus lesen, müssen Sie sich um nichts weiter kümmern als '\n'. Unabhängig davon, welche Darstellung das Betriebssystem verwendet, wird übersetzt.

    – Keith Thompson

    31. März 2013 um 20:15 Uhr

1433060cookie-checkPrüfen, ob ein Zeichen ein Zeilenumbruch ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy