problem mit readLine-Funktion



  • ich verwende eine funktion, die mir den input aus stdin liest:

    int readLine(char *input_line, unsigned max_length)
    {
      *input_line = NULL;
      unsigned int char_num = 0;
      char input_c = '\0';
    
      if(max_length<=0 || input_line==NULL)
        exitOnGeneralError("readLine");
    
      while((input_c = getchar()) != '\n')
      {
        *input_line++ = input_c;
        if(++char_num>=max_length)
          break;
      }
      *input_line = '\0';
      input_line = NULL;
      return char_num;
    }
    

    sieht jemand ein problem/einen fehler in dieser funktion?! es hat eigentlich immer alles wunderbar funktioniert, bis ich die funktion 2 mal hintereinander (mit 2 verschiedenen input_line-argumenten) aufrufen wollte:

    void andereFunktion(..)
    {
      char * index = malloc(sizeof(char));
      char * data = malloc(30 * sizeof(char));
      //...
    
      printf("Please insert data for first element\n index: ");
      readLine(index, 1);
      printf(" data:");
      readLine(data,30);
      //...
    
    }
    

    das erste readLine funktioniert noch, beim 2ten wird allerdings kein input mehr abgewartet sondern gleich 0 zurückgegeben! wenn ich das 1te readLine auskommentiere funkt das 2te einwandfrei 😡

    mache ich in der funktion irgendwas falsch? irgendwelche variablen nicht initialisiert?
    bin für jeden hinweis dankbar!

    mfg
    Sebastian



  • Hallo,

    füg das mal in deine Funktion ein, vor dem return:

    setvbuf ( stdin , NULL , _IONBF , 0 );
     setvbuf ( stdin , NULL , _IOFBF , BUFSIZ );
    

    Das löscht den Buffer, denn da ist noch ein \n mit drin, welches dein Problem verursacht.



  • hmm.. ich bin wieder mal verwirrt. jetzt funktionierts plötzlich, ohne dass ich viel verändert habe und ohne die setvbuf() commands.
    das sieht jetzt so aus:

    void andereFunktion(..)
    {
      char * index = malloc(sizeof(char));
      char * data = malloc(30 * sizeof(char));
      //...
      printf("Please insert data for first element\n");
      printf(" index: ");
      readLine(index, MAX_INDEX_LENGTH);
      printf(" data: ");
      readLine(data, MAX_DATA_LENGTH);
      //...
    }
    

    ich weiß leider nicht was ich getan habe, damit es geht.

    wenn ich allerdings in die readline funktion die von CarstenJ angegebenen zeilen einfüge dann wird nur das erste printf() ausgeführt, "index:" wird nicht mehr ausgegeben. woher kommt das? kann mir jemand bitte genauer erklären wie das mit dem buffer so läuft?!

    Sebastian



  • sebhofer schrieb:

    int readLine(char *input_line, unsigned max_length)
    {
      *input_line = NULL;
      unsigned int char_num = 0;
      char input_c = '\0';
      
      if(max_length<=0 || input_line==NULL)
        exitOnGeneralError("readLine");
    ...
    

    Na wenn es da mal nicht kracht. Überleg mal was passiert, wenn input_line wirklich auf NULL zeigt. Dabei solltest du dir speziell die erste Zeile in deiner Funktion ansehen.

    Zweites Problem:

    sebhofer schrieb:

    char * index = malloc(sizeof(char));
      char * data = malloc(30 * sizeof(char));
    

    Wieviel Speicher wurde für index reserviert? Und wieviele Zeichen schreibst du mit deiner Funktion rein? Schau dir dazu die GANZE Funktion an.

    Dann kommen wir zum dritten Teil:

    sebhofer schrieb:

    int readLine(char *input_line, unsigned max_length)
    {
      ...
      *input_line = '\0';
      input_line = NULL;
      return char_num;
    }
    

    Welchen Sinn macht es bitteschön, am Schluss input_line mit NULL zu überschreiben?



  • hi AJ,
    erstmal danke für die antwort.

    ad 1)
    ehrlich gesagt habe ich keine ahnung was dann passiert. ich wollte die variable einfach initialisieren (ist das hier nötig?). wäre

    *input_line = '\0';
    

    oder

    *input_line = '';
    

    besser?

    ad 2)
    hmm... klingt einleuchtend. da sollte ich wohl doppelt soviel allokieren.

    ad 3)
    weiß ich selber nicht, war nur als versuch gedacht, vielleicht mein problem zu lösen. andererseits: es schadet doch auch nicht, oder?

    thx
    sebhofer



  • sebhofer schrieb:

    ad 1)
    ehrlich gesagt habe ich keine ahnung was dann passiert. ich wollte die variable einfach initialisieren (ist das hier nötig?). wäre

    *input_line = '\0';
    

    oder

    *input_line = '';
    

    besser?

    Nein ist genauso schlimm. Überleg mal. Du schreibst erst einen Wert auf den Speicherbereich auf den du mit input_line zeigst und überprüfst erst dann, ob der Speicherbereich auf den input_line zeigt überhaupt "gültig" ist. Das ist das Problem.

    ad 2)
    hmm... klingt einleuchtend. da sollte ich wohl doppelt soviel allokieren.

    Bei index würde das noch zutreffen, aber bei data wäre es eigentlich Speicherverschwendung. Es geht mir da eigentlich nur darum, dass du das Stringendezeichen auch mit einberechnen musst beim Speicher reservieren.

    ad 3)
    weiß ich selber nicht, war nur als versuch gedacht, vielleicht mein problem zu lösen. andererseits: es schadet doch auch nicht, oder?

    Es dürfte zwar nichts ausmachen, aber es ist sinnloser Code. 😉



  • AJ schrieb:

    Nein ist genauso schlimm. Überleg mal. Du schreibst erst einen Wert auf den Speicherbereich auf den du mit input_line zeigst und überprüfst erst dann, ob der Speicherbereich auf den input_line zeigt überhaupt "gültig" ist. Das ist das Problem.

    mann, bin ich auf der leitung gestanden... jetzt hab ichs kapiert.

    danke für die hinweise, aber das hilft mir alles nicht mit meinem ursprünglichen problem. kannst du mir erklären wieso ich diese probleme mit dem "überspringen" der eingabe habe? was bleibt da im buffer was nicht soll, und wieso tut es dies auch wenn ich 2mal setenv(...) benutze?

    mfg
    sebastian



  • Könnte mir nur vorstellen, dass ein \n im Buffer bleibt, wie ja schon gesagt wurde.

    Aber am einfachsten findest du den Fehler, indem du mit dem Debugger Schritt für Schritt durchgehst. Dann siehst du gleich, wo genau was übersprungen wird und du kannst dir auch den momentanen Inhalt deiner Variablen anzeigen lassen, was meistens weiterhilft ;).



  • ok, dann ist das wohl die einzige möglichkeit.
    das problem ist, dass ich noch nicht herausgefunden habe, wie ich das mit meinem debugger mache hehe
    naja, ich werds herausfinden, danke jedenfalls

    sebastian



  • Dazu kann man dir wahrscheinlich in den Fachforen zu den Compilern bzw. IDE weiterhelfen (eins ist auch für alle anderen Compiler).


Anmelden zum Antworten