Problem fgets() für nächste Zeile



  • ja aber das problem ist: sie steht drin. er soll ja wenn die nicht gleich sind die 2 zeilen einfach die stink normale inpline rausschreiben.

    sinn des ganzen ist ja:
    1x odd + 1x even zusammenfassen + wenn z.b. 1x odd + 4x even vorkommt muss der ausgang sein: die odd-zeile + die 3 ersten even-zeilen.
    Wenn also die dqs_line nicht identisch ist mit der inpline, dann ist die dq_line für diese zeilenkombination unbrauchbar und gehört schon zur nächsten zeile.

    Ja ich hab breakpoints gesetzt.
    da kommt aber eben nicht das raus an zeilen, was nach dem programm her herauskommen müsste.



  • Dein Programm fasst aber nicht die "odd"- und "even"-Zeilen zusammen. Der Zeilenanfang wird auch schon mit verglichen. Das bedeutet, bei der Folge oeeee läuft die Schleife so ab:

    fgets(inpline) -> odd
    ->fgets(dqs_line) -> even1
      ungleich -> Ende
    
    fgets(inpline) -> even2
    ->fgets(dqs_line) -> even3
      gleich
      ->fgets(dq_line) -> even4
    

    Und effektiv wird die odd-Zeile im ersten Durchlauf und entweder even3 oder even4 im zweiten Durchlauf ausgegeben.

    Also nochmal ganz von vorne: Was genau willst du nach welchen Kriterien zusammenfassen?



  • Okay, ich erklär es nochmal anders:
    Eingangsdatei oben...
    Ich untersuche am ende der while schleife (wo ich die inpline einlese) immer ob es eine odd oder eine even war. je nachdem setze ich mode auf 1 oder 2.
    Dann liest die while die nächste zeile ein und stellt fest es ist z.b. eine even.
    Dann macht er ja nur etwas wenn mode auf 2 ist (also die zeile davor eine odd war).
    Also ist die inpline die erste even.
    Er schreibt dann die ersten 40 zeichen der inpline in eine neue datei.
    Dann soll er die nächste (dqs_line) einlesen und die mit der aktuellen inpline vergleichen und wenn die ersten 40 zeichen gleich sind weitermachen und die nächsten 4 zeichen hinten dran in die neue datei schreiben.
    Sollte jetzt die nächste zeile (dq_line) gleich sein (die 44 zeichen) dann soll er den rest aus der dq_line dran hängen. wenn nicht gleich, soll er die dqs_line dran hängen.
    und sollte allergdings gleich am anfang die dqs_line nicht mit der inpline übereinstimmen, dann einfach nur die inpline komplett rausschreiben.

    (ich hoffe die erklärung ist einigermaßen verständlich)



  • Ja, soweit komme ich mit - und was genau soll das Programm mit der dqs_line bzw. der dq_line machen, wenn sie nicht zu den gerade betrachteten Daten passen? Die Schleife dort oben verwirft sie einfach, so daß die jeweils erste "odd"- bzw. "even"-Zeile deiner Eingabedatei komplett unter den Tisch fällt.

    (Korrektur: Und nebenbei unterscheiden sich die Eingabezeilen bereits an Position 20 voneinander, so daß du wohl nie in den Abschnitt "und die nächsten 4 Zeichen hinten dran ... schreiben" kommst)



  • Nein, wenn 4 even zeilen hintereinander kommen schauen die ersten 3 bis position 44 identisch aus.
    wenn die dq_line, dqs_line nicht passen dann ignorieren (für die aktuelle zeile). Dann gehört sie zur nächsten zeile, die verarbeitet werden soll.

    Hier sieht man es besser...
    Die interessante Zeile ist jeweils die 3.
    Daher soll er immer die ersten xx zeichen vergleichen und dann eine zeile draus machen.
    Eingangsdatei

    even      WS_NN <101111100000000000000000ZZZZZZZZZZZZZZZZZZZZZZZ0100011>
    even      WS_NN <101111100000000000000000HHLLZZZZZZZZZZZZZZZZZZZ0100011>
    even      WS_NN <101111100000000000000000HHLLZZZLHLHLHLHLHLHLHLH0100011>
    odd             <011111100000000000000000ZZZZZZZZZZZZZZZZZZZZZZZ0100011>
    odd             <011111100000000000000000LLHHZZZZZZZZZZZZZZZZZZZ0100011>
    odd             <011111100000000000000000LLHHZZZHLHLHLHLHLHLHLHL0100011>
    even      WS_NN <101111100000000000000000ZZZZZZZZZZZZZZZZZZZZZZZ0100011>
    even      WS_NN <101111100000000000000000HHLLZZZZZZZZZZZZZZZZZZZ0100011>
    even      WS_NN <101111100000000000000000HHLLZZZLLHHLLHHLLHHLLHH0100011>
    odd             <011111100000000000000000ZZZZZZZZZZZZZZZZZZZZZZZ0100011>
    odd             <011111100000000000000000LLHHZZZZZZZZZZZZZZZZZZZ0100011>
    odd             <011111100000000000000000LLHHZZZHHLLHHLLHHLLHHLL0100011>
    


  • manu1984 schrieb:

    wenn die dq_line, dqs_line nicht passen dann ignorieren (für die aktuelle zeile). Dann gehört sie zur nächsten zeile, die verarbeitet werden soll.

    Und da ist möglicherweise das Problem - du ignorierst diese Zeilen nicht nur für den aktuellen Durchlauf, sondern endgültig.

    Hier sieht man es besser...
    Die interessante Zeile ist jeweils die 3.

    Ich bin jetzt echt zu faul, die Zeichen auszufählen 😉 Also könntest du bitte in Zukunft kennzeichnen, wo Position 41 bzw. 45 stehen?



  • ja das ist wahrscheinlich das problem. wie kriege ich es denn dann hin, dass er die zeilen nur für diesen durchlauf ignoriert???
    sonst brauch ich die ja!!!

    tut mir leid.
    zeile 41 - 45 sind die zeilen, wo immer 1100 - 0011 oder HHLL - LLHH steht.
    davor kommen meistens nur 0er.



  • 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