Eingabezeilen in mehrere kürzere Zeilen teilen



  • Also meine Aufgabe entspricht dem Titel, aber ich gehe darauf nochmal ein wenig genauer ein, denn ich muss ein Programm schreiben, dass eine Eingabezeile in mehrere kürzere Zeilen teilt und dies nach dem letzten Zeichen in einem Wort macht.

    Als Grundlage für dieses Problem hab ich ein Programm, dass die längste Zeile ausgibt, die man eingegeben hat.
    Vielleicht hilft uns da der Programmtext ein bißchen bei der Lösung:

    #include <stdio.h>
    
    #define MAXLINE 1000 /* Maximale Länge einer Eingabezeile */
    
    int max; /* Bisheriges Maximum */
    char line[MAXLINE]; /* momentane Eingabezeile */ 
    char longest[MAXLINE]; /* Bisher längste Zeile */
    
    int getline(void); /* Keine Wertrückgabe */
    void copy(void);
    
    /* längste Eingabezeile ausgeben (Spezielle Version) */
    
    main()
    
    {
    
    int len; /* Die Länge der Eingabenzeile ist ein Integer-Wert */
    extern int max; /*  Das bisherige Maximum nimmt auch einen Integer-Wert auch wenn man den Wert für externe Funktionen nutzen möchte. */
    extern char longest[]; /* Für die längste Zeile kann man ganzzahlige Zahlen nehmen und daher den char-Typ auch benutzen. */
    
    max = 0; /* Man gibt dem bisherigen Maximum erstmal einen Wert, damit es keinen Fehler bei der Ausgabe gibt */
     while ((len = getline()) > 0) /* während die Länge beim Einlesen der Zeile größer als Null sein muss,... */
     	if (len > max) /* ... nimmt man eine If-Schleife um eine bestimmte Bedingung zu schaffen. Wenn die Länge der jetzigen Zeile größer ist als das derzeitige Maximum, dann nimmt das Maximum den Wert von der Länge an, was auch vollkommen logisch erscheint. */
    	{
    	max = len;
    	copy(); /* Wenn dieser Fall zutrifft, dann wird der Wert sofort in die Copy-Funktion überführt und dann wird mit diesem Wert weitergerechnet. */
     } 
     if (max > 0) /*es gab überhaupt eine Zeile */
       printf("%s", longest); /* Die Ausgabe der bisher längsten Zeile wird ausgeführt*/
      return 0; /* Der Wert wird an main zurückgeliefert*/
     }
    
    /* getline: Spezielle Version */
    
    int getline(void)
    {
    
     int c, i; /*  Den beiden Variablen könnne nur Integerwerte annehmen*/
     extern char line[]; /* Man liest die derzeitige Eingabezeile ein */
    
    for (i=0; i < MAXLINE-1 && (c=getchar()) != EOF && c!='\n'; ++i)
    	line[i] = c;
     if (c == '\n') /*  Wenn das eingegebene Zeichen ein Zeilentrenner ist, dann... */
     {
     line[i] = c; /* Dann wird das Ende der derzeitigen Eingabenzeile erkannt und zwar durch C, dass den Zeilentrenner erkannt hat. */
     ++i; /* Man rechnet dann einfach eine Zeile weiter, weil dann die nächste Zeile für die nächste Eingabe frei ist. */
     }
     line[i]='\0'; /* Wenn das Ende der Zeile erreicht ist bzw des letzten Wortes bzw des letzten Zeichens dann wird der Wert der längsten Zeile zurückgegeben mit return */
     return i;
     }
    
    /* copy: Spezielle Version */
    
    void copy(void) /* Es kommt kein Wert an Copy zurück, denn es findet nur eine Wertübertragung statt, die im Hauptprogramm vorliegt und zeigt, dass Funktionen wieder sinnvoller sind, als ein zusammenhängender Programmtext. */
    
    {
    
     int i;
     extern char line[], longest[]; /* Es werden die beiden Variablen benutzt, die den Wert der Zeilen  und der längsten Zeile beinhalten. Sie sind gleichzusetzen mit den normalen Variablen aus dem Hauptprogramm und werden nur zur Erklärung in diesem Falle anders genannt */
    
     i = 0; /* Wertzuweisung, damit die Variable i überhaupt einen Wert besitzt */
     while ((longest[i] = line[i]) != '\0') /* Die längste Zeile liest die Zeile aus und endet das Lesen an der Stelle wo das Zeilenende ist. */
     ++i;
     } /* Die Deklarationen der extern-Variablen kann man auch in einer header-Datei sammeln und dort angeben. Diese Header-Datei kann man am Anfang  mit einer #include Anweisung mit der Endung ".h" verwenden. Die Verwendung von Variablen kann auch ganz extern geregelt werden, weil dadurch anscheinend eine Vereinfachung des Verstehens und Denkens existiert. Die ständige Verfügbarkeit ist zudem eine weiteres Kriterium bei dieser Problematik, da man ansonsten die Variablen immer wieder neu definieren müsste in jeder neuen und beliebigen Funktion. */
    


  • Dazu nur Drei bekerkungen:

    1: bitte NICHT foo(void), denn das ist redundant. wenn du KEIN Paramter übergeben willst- dann heißts foo()

    2: nicht main() sonder int main() MUSS es heißen

    3: ein Ununterschätzbarer Vorteil der kommentierung mit /* / ist das man Damit mehrer zeilen verwenden kann. das solltest Du mal schkleunigst ändern, weil nämlich sonst alle, die hier keine 1000020000 auflösung verwenden, kilometerweit nach Rechts scrollen müßen.



  • klug schrieb:

    1: bitte NICHT foo(void), denn das ist redundant. wenn du KEIN Paramter übergeben willst- dann heißts foo()

    nein, wir sind hier im C-Forum. foo() bedeutet, dass man belibig viele Parameter übergeben kann. Wobei ich nicht weiß, wo man sowas braucht.



  • Ich hab glaube ich einen Lösungsansatz gefunden mit mehreren Funktionen !

    Will von euch jemand die Lösung sehen ?



  • Soll hier jedes Wort einer Zeile in einer eigenen Zeile ausgegeben werden?



  • /bin/bash0R schrieb:

    Soll hier jedes Wort einer Zeile in einer eigenen Zeile ausgegeben werden?

    Ne das nicht aber das wäre auch mal ein Lösungsansatz. Ne in der kommenden Aufgabe soll etwa nach 10 Zeichen eine neue Zeile begonnen werden.



  • Ich hab es soweit hinbekommen, dass 10 Zeichen pro Zeile ausgegeben werden. Das Grundproblem liegt jetzt nur noch, dass er die Zeilen trennen soll und dabei keine Wörter schneiden darf.
    Wäre also ein Wort 8 Zeichen lang in der Zeile, dann würde man auch nur das Wort ausgeben.

    // Lange Eingabezeilen werden in kürzere Zeilen unterteilt //
    #include <stdio.h>
    
    #define MAXCOL 10 /* maximale Spalte der Eingabe */
    #define TABINC 8
    
    char line[MAXCOL]; /* Eingabezeile */
    
    int exptab(int pos); /* Austausch von Tabulatorzeichen durch Leerzeichen */
    int findblnk(int pos); /* Position des Leerzeichens finden */
    int newpos(int pos); /* line[] mit neuer Position umordnen */
    void printl(int pos); /* line[] bis Spalte pos ausgeben */
    
    /* Lange Eingabezeilen teilen */
    void main()
    {
      int c, pos; /* "c" ist das Zeichen und pos ist die Position */
    
      pos = 0; /* Position wird auf 0 gesetzt und damit auch intialisiert */
      while ((c = getchar()) != EOF) /*  */
      {
        line[pos] = c; /* "c" entspricht line[pos] */
        if (c == '\t') /*  wenn "c" ein Tabulatorzeichen ist, dann wird die folgende Anweisung ausgeführt */
    	pos = exptab(pos); /* Position entspricht der Position aus demr Funktion exptab */
        else if ( c == '\n') /* Wenn "c" ein Zeilentrenner ist, dann werden die folgenden Anweisungen ausgeführt */
        {
          printl(pos); /* aktuelle Eingabezeile ausgeben */
          pos = 0; /*  Position wird durch Wertevergabe initialisiert */
         } 
         else if (++pos >= MAXCOL) /* Die hochgezählte Position größer gleich der maximalen Eingabe in der Spalte (MAXCOL = 10) */
         {
           pos = findblnk(pos); /* Die Position des Leerzeichens wird auf die Position überschrieben */
           printl(pos); /* Funktion printl wird augerufen */
           pos = newpos(pos); /* Die Position wird übertragen auf die neue Position */
         }
      }
    }
    
    /* printl: line[] bis Spalte pos ausgeben */
    void printl(int pos) /* Die Funktion gibt einen Wert zurück */
    {
    int i; /* "i" wird Integertyp zu gewiesen */
    for (i = 0; i < pos; ++i) /*  */
    	putchar(line[i]); /* Gibt Zeile[i] aus */
    if (pos > 0) /* irgendetwas ausgeben? */
    	putchar('\n'); /* Zeilentrenner wird ausgegeben */
    }
    
    /* exptab: Tabulatorzeichen mit Leerzeichen darstellen */
    int exptab(int pos)
    {
    line[pos] = ' '; /* mindestens ein Leerzeichen */
    for (++pos; pos < MAXCOL && pos % TABINC != 0; ++pos) /* Initialisierung von Position, dann werden Vergleiche gemacht zwischen der jetzigen Postion und dem Wert der maximalen Zeichen in einer Zeile. Reinitialisierung von Position */
    	line[pos] = ' '; /*  */
    if (pos < MAXCOL) /* Noch Platz in aktueller Zeile */
     return pos; /* Rückgabe des Positionswertes */
    else {
    	printl(pos); /* Aufruf der Funktion "printl" */
    	return 0; /* Wenn alles funktioniert hat, dann wird der 0 zurückgegeben */
         }
    }
    
    /* findblnk: Position eines Leerzeichens finden */
    int findblnk(int pos)
    {
    while(pos > 0 && line[pos] != ' ') /* Während Position größer als null sein muss und die Position in der Zeile keine Leerstelle haben sollte, werden die nächsten Anweisungen ausgeführt */
    	--pos; /* Position wird dekrementiert */
    if (pos == 0) /* Keine Leerzeichen in Zeile */
     return MAXCOL; /* Derzeite maximale Anzahl der Zeichen in einer Spalte */
    else
    	return pos+1; /* Rückgabe des Wertes der Position + 1. Weil man in dieser Funktion ein Leerzeichen gefunden hat, geht man direkt zur nächsten Position über */
    
    }
    
    /* newpos: line[] mit neuer Position umordnen */
    int newpos(int pos)
    {
      int i, j; /* Integertypen für Variablen */
        j = 0;
      if (pos <= 0 || pos >= MAXCOL) /* Wenn Position kleiner gleich 0 oder Position größer gleich der maximalen Spalte der Eingabe */
        return 0; /* Nichts zu tun */
      else
      {
         /* i wird initialisert durch Wertevergabe */
        for (j = pos; j < MAXCOL; ++i) /* "j" bekommt Position zugewiesen und somit auch dessen Werte. Danach wird j größer MAXCOL verglichen und am Ende wird "i" inkrementiert */
        {
           line[i] = line[i] + line[j]; /* Die Gesamtzeile, die man neu erstellt, wird aus line[i] und line[j] bestehen */
    	++i; /* Inkrementierung von "i". Man geht in die nächste Zeile */
        }
        return i; /* Neue Position in line[] */
      }
    }
    

    So lautet bisher der Quellcode. Ich habe bei der Kontrolle der Variablen im Programmverlauf festgestellt, dass bei:

    line[i] = line[i] + line[j]; /* Die Gesamtzeile, die man neu erstellt, wird aus line[i] und line[j] bestehen */
    	++i; /* Inkrementierung von "i". Man geht in die nächste Zeile */
    

    eine Dauerwiederholungschleife mit unendlichem Ausgang entsteht, wodurch das Programm nie beendet wird.

    Wie kann man das Problem angehen oder habt ihr sogar generell eine neue Idee für den Quellcode.



  • cHillb3rT schrieb:

    void main()
    

    ist NICHT ansi-c
    richtig waere 'int main' - immer!
    jeder anstaenige compiler sollte, wenn er es schon akzeptiert, eine warnung ausgeben - diese sind grundsaetzlich zu beachten!
    'warnings' sind allein aus sicherheits-programmier-technischer sicht zu beachten!



  • Der Fehler lag im Detail einer Funktion:

    int newpos(int pos)
    {
      int i, j; /* Integertypen für Variablen */
        j = 0;
      if (pos <= 0 || pos >= MAXCOL) /* Wenn Position kleiner gleich 0 oder Position größer gleich der maximalen Spalte der Eingabe */
        return 0; /* Nichts zu tun */
      else
      {
        i = 0; 
        for (j = pos; j < MAXCOL; ++j) /* "j" bekommt Position zugewiesen und somit auch dessen Werte. Danach wird j größer MAXCOL verglichen und am Ende wird "i" inkrementiert */
        {
           line[i] = line[j]; /* Die Gesamtzeile, die man neu erstellt, wird aus line[i] und line[j] bestehen */
    	++i; /* Inkrementierung von "i". Man geht in die nächste Zeile */
        }
        return i; /* Neue Position in line[] */
      }
    }
    

    Damit geht es.... 😉 Das Wochenende hat mich da in der Hinsicht weiter gebracht !


Log in to reply