Problem fgets() für nächste Zeile



  • Du hast die nächste zu bearbeitende Zeile in dqs_line bzw. dq_line stehen, also müsstest du sie (anstelle des fgets()-Aufrufes) umkopieren nach inpline (stichwort strncpy()), bevor du wieder in die Schleife reinspringst.



  • das verstehe ich jetzt nicht so ganz.
    ich muss die zeile doch einlesen. ich kann natürlich die zeile dqs_line umkopieren in inpline, aber dann liest er doch von der while-schleife, die um den ganzen spass ist wieder die nächste zeile ein, oder?



  • Du hast diese Zeile schon eingelesen, also mußt du sie nicht nochmal einlesen (wenn du unbedingt willst, müsstest du den Lesezeiger entsprechend zurückschieben). Und natürlich müsstest du auch die umliegende While-Schleife so anpassen, daß sie nicht nochmal einliest 😉



  • ja aber das verstehe ich komplett nicht wie ich das machen soll.
    mit rewind() kann ich einen zeiger doch zurück setzen, oder?

    aber wie soll ich die while-schleife anpassen?
    mir ist schon klar, dass ich die nächsten 2 zeilen schon eingelesen habe, aber ich weiss nicht wie ich den zeiger auf die position der eigentlichen inpline setzen kann 😞



  • Der direkte Weg: fseek(fcache,-(strlen(dqs_line)+1),SEEK_CUR); (die '+1' steht für das \r, das beim Einlesen unter den Tisch gefallen sein könnte - mußt du eventuell nachjustieren).

    Der bessere Weg: Du reduzierst die Schleifenbedingung auf while(!feof(fcache)) und kopierst am Ende der Schleife den Inhalt von dqs_line bzw. dq_line nach inpline (je nachdem, welche Eingabezeile nicht mehr zum Vorgänger gepasst hat - wenn beide Zeilen korrekt waren, holst du die neue Anfangszeile per fgets()).



  • okay, also das mit fseek() verstehe ich, allerdings wenn ich das so eingebe läuft das programm nicht mehr durch sondern bleibt in der while-schleife stehen.

    die andere lösung ist mir noch etwas unklar.
    soweit ich es glaube zu verstehen:

    ich kopiere mir am ende der while-schleife die dqs_line nach inpline und
    dq_line nach dqs_line. Dann komme ich allerdings mit meinen fgets() durcheinander, weil ich ja dann wieder 2 neue zeilen einlese.
    Also habe ich dann auf einmal 4 zeilen.
    Aber am anfang für den ersten schritt muss ich ja 3 zeilen einlesen um den vergleich zu machen ...



  • Jetzt hast du vermutlich zu viel kopiert.
    Du hast drei mögliche (reguläre) Fälle (in der Reihenfolge, wie sie im Originalpost abgefangen werden):

    1. dqs_line un dg_line passen zu inpline (Zeile 20/21):
      Der nächste Block beginnt mit einer neuen Eingabezeile -> fgets(inpline,...)
    2. dqs_line passt, dq_line ist falsch (Zeile 25/26):
      dq_line ist der Anfang des nächsten Blocks -> strcpy(inpline,dq_line)
    3. dqs_line ist falsch (Zeile 31-33):
      dqs_line ist der Anfang des nächsten Blocks, dq_line wurde gar nicht eingelesen -> strcpy(inpline,dq_line)


  • also ich hab die schleifen jetzt mal modifiziert, dann bleibt er auch in der while hängen.

    aber dafür habe ich die lösung mit fseek() hinbekommen.
    aber: rein logisch muss ich den zeiger ja dann 2 zeilen hochsetzen.
    und 2 zeilen lässt er sich nicht zurücksetzen. dann bleibt er auch in der while hängen.

    while(!feof(fcache)) {
            if(mode == 0)
    	   fgets(inpline,MAXLENGTH,fcache);
    
        if(mode == 1 && strncmp(inpline,"odd             <01",18)==0)
          {
    	    fprintf(fmake_list,"odd             <");
    	 	for(i=17;i<41;++i)
    	        fprintf(fmake_list,"%c",inpline[i]);	  
    
    	    fgets(dqs_line, MAXLENGTH, fcache);
    	    fgets(dq_line, MAXLENGTH, fcache);
    
            if(strncmp(dqs_line,inpline,40)==0 && strncmp(dq_line,"even",4)!=0)
                { 
    			  for(i=41;i<45;++i)
    		          fprintf(fmake_list,"%c",dqs_line[i]);
    			  if(strncmp(dqs_line,dq_line,44)==0)
    			    {
    				  for(i=45;inpline[i]!='\n';++i)
    		              fprintf(fmake_list,"%c",dq_line[i]);
    			      strcpy(inpline,dq_line);
    				}
    			  else
    			    {
    				  for(i=45;inpline[i]!='\n';++i)
    		              fprintf(fmake_list,"%c",dqs_line[i]);
    			      strcpy(inpline,dqs_line);
    				}
    
    			  fprintf(fmake_list,"\n");
    			}
    	      else
    			{
    			  for(i=41;i<45;++i)
    		          fprintf(fmake_list,"%c",inpline[i]);
    			  for(i=45;inpline[i]!='\n';++i)
    		          fprintf(fmake_list,"%c",inpline[i]);
    			  fprintf(fmake_list,"\n");
    			  mode = 0;
    			}
    


  • Also inzwischen blicke ich auch nicht mehr durch, was du da eigentlich machst - das ist wohl der ideale Zeitpunkt, dein gesamtes System zu überdenken (notfalls beginnend mit dem Eingabeformat - wozu sind überhaupt drei Eingabezeilen nötig, die du dann doch nach solch komplizierten Regeln zu einer zusammenpuzzlen mußt?).



  • naja, also was ich versucht habe:

    wenn nur die inpline gebraucht wird, nix kopieren und er soll einfach die nächste zeile als inpline einlesen.
    wenn die dqs_line mit eingelesen wird aber nicht gepasst hat soll er die dqs_line in die inpline kopieren.
    wenn die dq_line eingelesen wurde allerdings nicht passt aber die dqs_line gepasst hat: dq_line -> inpline.

    also der sinn:
    das sind bitmuster und schreibvorgänge sind in dem vorherigen format immer 2x der gleiche "vektor", die eben alle 2 informationen dazu beitragen.
    Die lesevorgänge haben 3 vektoren und setzen ihre infos aus den 3 vektoren zusammen.
    (even = logische 1 , odd = logische 0) und das wird dann eben am ende immer abwechselnd, dass man ein schönes signal hat.

    wieso 2-3 zeilen einlesen:
    eingangs datei ist so aufgebaut:
    odd Write 1 + 1 oder 2 even (variiert) -> EVEN
    even Write 2
    even Write 3
    even + nächster odd -> ODD
    odd
    odd + nächster even -> EVEN
    even
    ...



  • Args, das sieht ganz danach aus, als ob meine Signatur besser auf dich passen würde 😃

    (was programmierst du eigentlich? Und was für einen Sinn soll so ein Eingabeformat haben?)



  • ja das stimmt.
    deine signatur trifft auf mich 110% zu 🙂

    ich programmiere einen "converter" der einfach das eine "format" in ein anderes umwandeln soll.
    das eingangsformat kann man sich so vorstellen:
    man hat ein messgerät, welches in bestimmten zeitabständen die signale misst.
    jetzt kann es z.b. sein, man hat 5 sekunden logische 1 (even) und misst das signal alle 2 sekunden.
    also bekommt man messdaten bei
    zeit = 0 , 2 , 4
    oder zeit = 1 , 3 , 5
    oder zeit = 2 , 4

    daher kann es eben vorkommen dass so eine logische "1" 3x drinsteht und manchmal eben nur 2x.



  • Ich hab es nochmal komplett neu versucht nur mit 2 zeilen.
    Problem: er liest immer die gleiche zeile ein und geht nicht zur nächsten!

    while(!feof(fcache)) {
    
    	if(mode == 0 || strcmp(dqs_line,"")==0) // Lese Zeile 1+2
    	   fgets(inpline,MAXLENGTH,fcache);
    
        if(mode == 1 && strncmp(inpline,"odd             <01",18)==0)
    	  {
    	     fprintf(fmake_list,"odd             <");
    	     for(i=17;i<41;++i)
    		    fprintf(fmake_list,"%c",inpline[i]);
    
    		 fgets(dqs_line,MAXLENGTH,fcache);
    		 if(strncmp(inpline,dqs_line,41)==0)
    		   {
    		     for(i=41;i<45;++i)
    		         fprintf(fmake_list,"%c",dqs_line[i]);
    		     strcpy(dqs_line,"");
    		   }
    		 else
    		   {
    		     for(i=41;i<45;++i)
    		         fprintf(fmake_list,"%c",inpline[i]);
    		     strcpy(inpline,dqs_line);
    		   }
    
    		 fprintf(fmake_list,"\n");	  
    	  }
    
        if(strncmp(inpline,"even      WS_NN <10",18)==0)
           mode = 1;
        else if(strncmp(inpline,"odd             <01",18)==0)
           mode = 2;
    

Anmelden zum Antworten