K&R Übung 1.16 – Begrenzung der Zeilenlänge

Lesezeit: 7 Minuten

Benutzer-Avatar
Andrej Buschmann

Ich lerne C von K&R’s “Die Programmiersprache C” Buch. Ich mache die Übungen, die im Buch angegeben sind. Ich bin bei Übung Nummer 1.16, aber ich verstehe sie nicht.

Aufgabe 1.16:

Überarbeiten Sie die Hauptroutine des Programms für die längste Zeile, damit es die Länge beliebig langer Eingabezeilen und so viel wie möglich des Textes korrekt druckt.

Meine Fragen:

  1. “… so viel wie möglich vom Text …” – gibt es eine Beschränkung der Zeichenfolgenlänge? Vielleicht gibt es in Standard-Headern eine Variable mit dem maximal zulässigen Wert der Zeichenfolgenlänge?

  2. “…die Länge von beliebig langen Eingabezeilen…” – aber im Code ist MAXLINE als 1000 definiert. Es ist auch eine begrenzte Größe. Ich sehe einige Lösungen hieraber meiner Meinung nach ist es keine Lösungsentscheidung, da bei ersterem eine Beschränkung der Zeilenlänge (1000 Zeichen) besteht.

Vielleicht habe ich die Aufgabe nicht verstanden. Soweit ich weiß, muss ich die 1000-Zeichen-Beschränkung aufheben.

  • Ich habe mein K&R jetzt nicht dabei, daher kann ich die Anforderungen des längsten Programms nicht wirklich überprüfen. Denken Sie jedoch daran, dass Sie einzelne Zeichen lesen, drucken und zählen können, ohne sie in einer Zeichenfolge speichern zu müssen.

    – pmg

    27. Februar 2013 um 18:45 Uhr


  • @pmg Aber nach dem Text der Aufgabe muss ich auch den maximalen Zeilentext drucken.

    – Andrej Buschmann

    27. Februar 2013 um 18:49 Uhr


  • Nun … wenn Sie die längste Zeile drucken müssen, müssen Sie sie irgendwo speichern. Mein Vorschlag ist nicht gut für die Übung, sorry.

    – pmg

    27. Februar 2013 um 19:01 Uhr

  • Sie müssen jedoch nicht alles auf einmal speichern.

    – Karl Norum

    27. Februar 2013 um 19:06 Uhr

Benutzer-Avatar
Nr

Es ist eine ziemlich frühe Übung in K&R, Sie sollten nur einige geringfügige Änderungen am Code vornehmen, keine vollständige Neugestaltung des Codes.

  1. “…so viel wie möglich vom Text…”

    die Interpretation liegt bei Ihnen. Ich würde es tun, indem ich drucke, was in der gespeichert ist longest Puffer. dh bis zu 1000 Zeichen der Zeile ausdrucken. Auch hier handelt es sich um eine frühe Übung mit noch wenig Einführung in dynamisch zugewiesenen Speicher. Und zu der Zeit, als K&R geschrieben wurde, war das Speichern von beliebig langen Textzeilen noch nicht so machbar wie heute.

  2. “…die Länge beliebig langer Eingabezeilen…”

    Ist eine harte Anforderung. Sie sollen die richtige Länge finden, egal wie lang sie ist (zumindest innerhalb der Grenzen von einer int. )

Eine Möglichkeit, dieses Problem zu lösen, ist:

  • Prüfen Sie nach dem Aufruf von getline(), ob das letzte Zeichen in die eingelesen wurde line Puffer ist ein Zeilenumbruch (‘\n’)
  • Wenn ja, lesen Sie eine ganze Zeile. Das len Variable ist die korrekte Länge der Zeile (der Rückgabewert von getline()), und im Vergleich zum ursprünglichen Code ist keine besondere Überlegung erforderlich.
  • Wenn ja nicht , haben Sie nicht die gesamte Zeile gelesen und müssen nach dem Ende dieser Zeile suchen. Sie fügen eine While-Schleife hinzu, rufen getchar() auf, bis es einen Zeilenumbruch (oder EOF) zurückgibt, und zählen die Anzahl der Zeichen, die Sie in dieser Schleife lesen. Mach einfach len++ zählen.
  • Wenn die While-Schleife fertig ist, wird die neue len ist jetzt die tatsächliche Länge der Zeile, aber unser Puffer enthält nur die ersten 999 Zeichen davon.
  • Wie zuvor speichern Sie den Strom ab (Aufruf der Funktion copy()). line Puffer (max. 1000 Zeichen), wenn diese Zeile bisher die längste ist.
  • Wenn Sie fertig sind, drucken Sie die gespeicherte Zeile wie zuvor aus (die longest Puffer) und die max variabel für die Länge.
    • Aufgrund der oben erwähnten While-Schleife that max Länge stimmt jetzt.
    • Wenn die longest Zeile war tatsächlich länger als 1000 Zeichen. Sie drucken zumindest diese ersten 999 Zeichen aus – was “so viel wie möglich” ist.

Ich werde es nicht verderben und den Code posten, den Sie benötigen, um dies zu erreichen, aber es sind nur 6 Codezeilen, die Sie dem Programm mit der längsten Zeile von Übung 1-16 hinzufügen müssen.

  • Vielen Dank. Ich werde versuchen, es ins Russische zu übersetzen und morgen Code zu schreiben. Jetzt ist Nacht, und ich will schlafen. Dank an alle!

    – Andrej Buschmann

    27. Februar 2013 um 19:22 Uhr


  1. Auf modernen Computern ist “so viel wie möglich Text” wahrscheinlich der gesamte Text, dank Terminalprogrammen mit automatischem Zeilenumbruch. Dieses Buch wurde geschrieben, als noch Fernschreiber in Gebrauch waren. Es gibt keine Begrenzung der String-Länge, außer vielleicht Speicherbeschränkungen des Computers, an dem Sie arbeiten.

  2. Sie erwarten, dass Sie eine Art Schleife hinzufügen, um Zeichen zu lesen und nach Zeilenumbrüchen zu suchen, anstatt anzunehmen, dass ein Lesevorgang in die MAXLINE Der große Puffer wird mit Sicherheit einen Zeilenumbruch enthalten.

  • Ich erinnere mich, das irgendwo gelesen zu haben 4096 Zeichenbegrenzung pro Zeile in einer Textdatei unter Linux. Es wird jetzt darüber hinaus unterstützt? seit wann?

    – जलजनक

    27. Februar 2013 um 18:52 Uhr


  • automatically line-wrapping terminal programs – Was ist es?

    – Andrej Buschmann

    27. Februar 2013 um 18:53 Uhr


  • @DoSparKot, versuchen Sie es – Sie werden sicher sehen, dass es keine solche Grenze gibt. Ich habe noch nie von so etwas gehört.

    – Karl Norum

    27. Februar 2013 um 18:56 Uhr


  • @Bush – ein Terminalprogramm, das Text in die nächste Zeile umbricht, wenn er die rechte Seite des Fensters erreicht. Wie Zeilenumbruch in einer Textverarbeitung.

    – Karl Norum

    27. Februar 2013 um 18:57 Uhr

  • äh.. es war fgets() und die LINE_MAX Grenze.

    – जलजनक

    27. Februar 2013 um 19:41 Uhr

Benutzer-Avatar
Rot

hier ist meine version:

int getline(char s[],int lim)
{
    int c,i;
    for(i=0;i<lim-1&&(c=getchar())!=EOF&&c!='\n';++i)
        s[i]=c;
    if(c=='\n')
    {
        s[i]=c;
        ++i;
    }
    if(c!=EOF)
    {
        while((c=getchar())!=EOF&&c!='\n')
            i++;
    }
    s[i]='\0';
    return i;
}
    #define MAXLINE 1000
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max=0;
    while((len=getline(line,MAXLINE))>1)
    {
        if(len>max)
        {
            max=len;
            copy(longest,line);
        }
    }
    if(max>0)
    {
        printf("%d:%s",max,longest);
    }
    return 0;

Aus unbekannten Gründen funktioniert der Beispielcode auf meinem PC nicht besonders. Wenn die Bedingung “len> 0” ist, endet die Schleife nicht. Ich denke, der Hauptgrund ist, dass Sie nichts eingeben, aber trotzdem müssen Drücken Sie die Eingabetaste, damit es als ‘\n’ empfangen wird und die Länge 1 ist; Ich denke, es erfüllt die Anforderung, dass die Länge beliebig langer Eingabezeilen und so viel Text wie möglich gedruckt werden.
Und es funktioniert so



    #include

    main()
    {
       long tlength = 0;
       short input, llength = 1;
       while (llength > 0)  {
          llength = 0;
          while ((input = getchar()) != EOF) {
              ++llength;
              if (input == '\n')
              break;
          }
          tlength = tlength + llength;
          printf("\nLength of just above line : %5d\n\n", llength);
       }
       printf("\n\tLength of entire text : %8ld\n", tlength);
       return 0;
    }

Meiner Meinung nach möchte diese Frage nur die Länge jeder beliebigen Zeile + schließlich die Länge des gesamten Textes.

Versuchen Sie, diesen Code auszuführen, und sagen Sie mir, ob er gemäß der Frage richtig ist, da ich in diesem Problem zu verwirrend bin.

Ich möchte anmerken, dass diese Übung tatsächlich sinnvoller ist, wenn Sie sich vorstellen, dass die Grenze für die Anzahl der Zeichen, die Sie kopieren können, sehr klein ist – sagen wir 100 Zeichen – und dass Ihr Programm zwischen längeren Zeilen unterscheiden soll Grenze.

(Wenn Sie das Limit tatsächlich so ändern, dass es sehr klein ist, wird der Code einfacher zu testen: Wenn es die erste Zeile auswählt, die dieses kleine Limit erreicht, wissen Sie, dass Ihr Code nicht funktioniert, während es die erste zurückgibt wie auch immer – viele Zeichen der längsten Zeile, es funktioniert.)

Behalten Sie den Teil des Codes, der Zeichen kopiert und zählt, bis er einen Zeilenumbruch oder EOF oder das Zeilengrößenlimit erreicht. Fügen Sie Code hinzu, der dort weitermacht, wo dieses Zählen und Kopieren aufhört, und der auch dann weiterzählt, wenn das Kopieren beendet ist, solange getchar() noch kein EOF oder einen Zeilenumbruch zurückgegeben hat.

Benutzer-Avatar
Anshu

Meine Lösung: direkt unter dem Aufruf von getLine

if ( line[len-1] != '\n' && line[len-1] != EOF) //if end of line or file wasnt found after max length
{
    int c;
    while ( ( c = getchar() ) != '\n' && c != EOF ) 
        len++; //keep counting length until end of line or file is found
}

Um es zu testen, ändern Sie MAXLINE auf 25

1205760cookie-checkK&R Übung 1.16 – Begrenzung der Zeilenlänge

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

Privacy policy