2016-06-03 12 views
0

vor allem ich bin neu in der Codierung in C.Wie liest man Eingabezeichenfolge bis eine Leerzeile in C?

Ich habe versucht, eine Zeichenfolge unbekannter Größe vom Benutzer zu lesen, bis eine leere Zeile angegeben ist, und speichern Sie es in eine Datei, und danach zu lesen Datei.

Ich habe es nur geschafft, bis eine neue Zeile angegeben ist und ich weiß nicht, wie ich nach einer Leerzeile suchen soll.

#include <stdio.h> 
#include <stdlib.h> 

char *input(FILE* fp, size_t size) { 
    char *str; 
    int ch; 
    size_t len = 0; 
    str = realloc(NULL, sizeof(char)*size); 
    if (!str)return str; 
    while (EOF != (ch = fgetc(fp)) && ch != '\n') { 
     str[len++] = ch; 
     if (len == size) { 
      str = realloc(str, sizeof(char)*(size += 16)); 
      if (!str)return str; 
     } 
    } 
    str[len++] = '\0'; 

    return realloc(str, sizeof(char)*len); 
} 

int main(int argc, const char * argv[]) { 
    char *istr; 
    printf("input string : "); 
    istr = input(stdin, 10); 
    //write to file 
    FILE *fp; 
    fp = fopen("1.txt", "w+"); 
    fprintf(fp, istr); 
    fclose(fp); 

    //read file 
    char c; 
    fp = fopen("1.txt", "r"); 
    while ((c = fgetc(fp)) != EOF) { 
     printf("%c", c); 
    } 

    printf("\n"); 
    fclose(fp); 

    free(istr); 
    return 0; 
} 

Vielen Dank!

+3

'EOF' kann nicht in' char' gespeichert werden, daher sollte der Typ von 'c' zum Speichern des von' fgetc() 'zurückgegebenen' 'int' sein. – MikeCAT

+0

@MikeCAT Meinst du das ernst? ist auf den meisten Systemen nicht "EOF" (-1)? Ein vorzeichenbehaftetes Zeichen kann einen Wert zwischen -128 und 127 speichern –

+1

@layzak Ja. Zeichen, die von 'fgetc()' zurückgegeben werden, sind ein Bereich von 'unsigned char'. Das Konvertieren von 'EOF' in" char "ist keine gute Idee, da es nicht möglich ist, eines von möglichem Zeichen und' EOF' zu unterscheiden. – MikeCAT

Antwort

1

Warum nicht eine Flagge oder einen Zähler verwenden. Für einen Zähler können Sie einfach den Zähler jedes gefundenen Zeichens erhöhen. Wenn eine neue Zeile gefunden wird und der Zähler 0 ist, muss es eine Leerzeile sein. Wenn ein neues Zeilenzeichen gefunden wird und der Zähler nicht 0 ist, muss es das Ende der Zeile sein, also setze den Zähler auf 0 zurück und fahre fort.

Etwas wie folgt aus:

int count = 0; 
while ((ch = fgetc(fp)) != EOF) 
{ 
    if(ch == '\n') 
    { 
     if(count == 0) 
     { 
      break; 
     } 
     count = 0; 
     str[len++] = ch; 
    } 
    else 
    { 
     str[len++] = ch; 
     ch++; 
    } 
} 

Eine andere Möglichkeit wäre, einfach zu überprüfen, ob das letzte Zeichen in der Zeichenfolge eine neue Linie war.

while ((ch = fgetc(fp)) != EOF) 
{ 
    if(ch == '\n' && str[len - 1] == '\n') 
    { 
     break; 
    } 
} 
+0

das hat funktioniert, danke! –

1

Eine leere Zeile ist eine Zeile, die nur einen Zeilenumbruch enthält, richtig? So können Sie einfach die letzten 2 Zeichen behalten, die Sie gelesen haben. Wenn sie '\n' sind, haben Sie eine leere Zeile gefunden: die erste '\n' ist das Ende der vorherigen Zeile, die zweite ist das Ende der aktuellen Zeile (die eine leere Zeile ist).

char *input(FILE* fp, size_t size) { 
    char *str; 
    int ch, prev_ch; 
    size_t len = 0; 
    str = realloc(NULL, sizeof(char)*size); 
    if (!str)return str; 
    while (EOF != (ch = fgetc(fp)) && (ch != '\n' && prev_ch != '\n')) { 
     str[len++] = ch; 
     if (len == size) { 
      str = realloc(str, sizeof(char)*(size += 16)); 
      if (!str)return str; 
     } 
     prev_ch = ch; 
    } 
    str[len++] = '\0'; 

    return realloc(str, sizeof(char)*len); 
} 

Beachten Sie, dass um ch != '\n' && prev_ch != '\n' Klammer sind hier die Bedingung verständlicher zu machen.

Um dies zu verbessern, können Sie Ihre Funktion beibehalten, die nur eine Zeile liest und testen, ob die zurückgegebene Zeile leer ist (sie enthält nur eine '\n').

+0

das ist nicht möglich, wenn' ch' ist '\ n' dann wird' prev_ch' auch '\ n' und dann bin ich im selben Problem. –

+0

Ja, aber 'prev_ch' wird' '\ n'',' ch' ist das nächste Zeichen. – blatinox

2

Ich würde Ihren Code ein wenig umstrukturieren. Ich würde Ihre input() Funktion ändern, um eine Funktion zu sein (readline()?), Die eine einzelne Zeile liest. In main() würde ich Schleife lesen Zeile für Zeile über readline().

Wenn die Zeile leer ist (nur einen Zeilenumbruch hat - verwenden Sie strcmp(istr, "\n")), geben Sie den Zeiger frei und beenden Sie die Schleife. Andernfalls schreibe die Zeile in die Datei und gib den Zeiger frei.

Wenn Ihr Konzept einer leeren Zeile " \n" (Präfix Leerzeichen) enthält, dann schreiben Sie eine Funktion is_only_spaces(), die einen wahren Wert für eine Zeichenfolge zurückgibt, die so aussieht.

Während Sie mit der leeren Zeile in input() umgehen konnten, gibt es einen Wert beim Abstrahieren der Zeilenlesung von den Eingabeterminierungsbedingungen.

Verwandte Themen