Zeile leer?



  • Hallo.

    Ich lese in ANSI C eine Zeile einer beliebigen Textdatei mit diesem Source ein:

    char *buffer[256];
    fgets(buffer, sizeof(buffer), fp);
    

    Ich lese also Zeilenweise ein...
    Wie ueberpruefe ich nun in Buffer ob eine aktuelle Zeile leer ist sprich dort habe ich im Editor eine Leerzeile eingebaut?

    Danke!



  • 1. Definiere "leere Zeile"
    2. Prüfe ob Buffer Definition entspricht

    Beispiel:
    1. Zeile besteht aus Zeilenende-Zeichen ('\n'), nicht mehr und nicht weniger
    2. Prüfe ob strlen(buffer) == 1 und einziges Zeichen == '\n'

    PS: Du solltest den Rückgabewert von fgets prüfen, denn so kann es im Fehlerfall passieren dass buffer garnicht geändert wurde.



  • strlen liefert in meinem Beispiel garnichts (keinen integer) zurueck...
    buffer[0] ist weder '\n' noch '\0' und *buffer ist auch nicht false.



  • Da strlen einen Integer zurückgibt glaube ich Dir die erste Behauptung mal nicht (es seidenn das Programm stürzt bei strlen ab - dann hast Du den Speicher vermurkst).

    Was ich damit sagen will:

    strlen(buffer); /* Auch hier gibt strlen etwas zurück, Du machst nur nichts damit */
    

    Wie wäre es wenn Du Dir den Wert von buffer[0] und von strlen(buffer) mal ausgeben lässt? Spekulieren ist nicht so toll.



  • Ich meinte mit strlen gibt bei dieser gewissen leeren Zeile, das ich mir es schon ausgegeben lassen hatte... 😉
    Also so:

    printf("%d",strlen(buffer));
    

    Somit gibt diese Zeile NICHTS aus... andere Zeilen geben ihre laenge aus.

    if(fgets(buffer, sizeof(buffer),fpconf)!=NULL)
          printf("%s",buffer[0]);
    

    Das hier oben gibt eine Speicherzugriffsfehler...

    [18:29] <wave> is that a hack: sprintf(buffer,"%s\0",buffer); ? if yes it doesn't matter... at least it works
    [18:29] <scuzzy> no, it just doesn't make any sense
    [18:29] <scuzzy> the buffer ittself has to be null terminated
    [18:29] <scuzzy> sprintf is going to look inside buffer for the null
    [18:29] <scuzzy> not the string format
    [18:30] <scuzzy> well, I mean
    [18:30] <scuzzy> it'd kinda work
    [18:30] <scuzzy> but not qutie
    [18:30] <scuzzy> the problem is
    [18:30] <scuzzy> buffer is not null terminated to begind with, so it's not going to find the end, for you yo null terminate
    [18:30] <scuzzy> does that make sense?
    [18:30] <wave> i also thought %s is also terminated.... but it seems not to be o0
    [18:31] <sata_> scuzzy: get som sleep
    [18:31] <wave> it makes sense... because i make sure that the line i read in is terminated even if it is not...
    [18:32] <wave> so i can verify via asking buffer[2]!='\0'
    [18:32] <scuzzy> wave: yes, but sprint doesn't know when to stop



  • Glaube mir, auch dieser printf hat etwas ausgegeben (auch wenn Du es vielleicht nicht gesehen hast weil der Zeilenwechsel \n fehlt). Überhaupt gibt der Formatbezeichner %d immer irgendeine Zahl aus, selbst wenn Du keine übergibst (okay, da darf dann auch das Programm abstürzen 😉 )

    Der zweite printf gibt einen Zugriffsfehler weil %s eine String-Adresse erwartet, Du ihm aber den Ascii-Code des ersten Zeichen lieferst. Richtig wäre

    printf("%s\n", buffer); // Ganze Zeile
    

    oder

    printf("%c\n", buffer[0]); // Erstes Zeichen
    

    oder

    printf("%d\n", (int)buffer[0]); // ASCII-Wert vom ersten Zeichen
    

    Und drittens hat Scuzzy recht, sprintf sucht in dem String auf der rechten Seite selbst nach einem \0 um zu wissen wann das Ende erreicht ist, also ist dieser Befehl wirklich überflüssig (mit dem Unterschied dass hinterher am Ende zweimal \0 in buffer steht).



  • richtig, und das am ende von buffer eine "\0" steht moechte ich ja eigentlich auch genau erreichen...

    Nochmal zu printf, das geht doch auch so hier da printf eine refferenz (sprich addresse verlangt):

    printf("%s",&buffer[0])
    

    Und nochmal ein Frage, was heisst dort das %c. Das er die Adresse davon nehmen soll oder so?

    Ja und nochwas, printf hat vorhin tatsaechlich bei buffer[0] eine neue zeile begonnen aber ich konnte nich mit buffer[0]=='\n' das abfragen; warum denn nicht?

    Danke fuer deine Antwort!



  • Erster Punkt zu deinem Programm oben: du brauchst kein Array von char-Pointern, sondern ein Array von char's (also entweder "char buffer[size];" oder "char* buffer=malloc(size);" (inklusive passendem free()-Aufruf)).

    Zweiter Punkt: man: fgets schreibt das \n mit in den String - wenn die Zeile leer war, sollte es also an Position buffer[0] stehen.

    PS: Und was die Format-Symbole von man: printf(3) bedeuten, kannst du in jedem besseren Manual nachlesen (%s interpretiert den Parameter als char* und gibt alles dehinet bis zum \0 aus, %c interpretiert ihn als char (Einzelzeichen)).



  • wave schrieb:

    richtig, und das am ende von buffer eine "\0" steht moechte ich ja eigentlich auch genau erreichen...

    Nochmal:
    sprintf gibst Du eine Adresse, die von Buffer. sprintf soll die Zeichen an dieser Adresse ausgeben. Damit er weiss wieviele Zeichen er ausgeben soll sucht er nach dem \0.... D.h. es IST schon da - sonst würde sprintf nicht aufhören nach ihm zu suchen! Die Anweisung ist und bleibt sinnlos.

    Nochmal zu printf, das geht doch auch so hier da printf eine refferenz (sprich addresse verlangt):

    printf("%s",&buffer[0])
    

    Ja, geht auch, ist aber einfacher nur "buffer" zu schreiben 😉

    Und nochmal ein Frage, was heisst dort das %c. Das er die Adresse davon nehmen soll oder so?

    "%c" bedeutet genau ein einzelnes Zeichen - und da übergibst Du bitte auch ein Zeichen, keine Adresse.

    Printf ist nicht typsicher, es verlässt sich darauf dass Du ihm das gibst was Du im Formatstring behauptest zu übergeben - wenn Du mit "%c" formatierst aber eine Adresse übergibst passieren komische Sachen.


Anmelden zum Antworten