übertrittsfehler??



  • hallo leute

    ich hatte dir aufgabe ein programm zu schreiben welches ein dateiformat in ein anderes übersetzt, war auch kein problem, in c++ das kann ich ja...
    als ich fertig war und das am server compilen wollte seh ich das da nur ein c compiler drauf ist... also musste ich das programm auf c abändern...
    hab ich jetzt fast fertig nur hab ich übertrittsfehler, glaub ich, könnt ihr euch das source anschaun und mir tipps geben was ich falsch gemacht hab, es ist das erste mal das ich was in c gemacht hab...

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    void Umschreiben(char *Alles, char *Text1, int wo)
    {strncpy(Text1,Alles, wo);
     strcpy(Alles,Alles+wo);
    }
    
    int Suchen(char *Alles, int wo)
    {int laenge=strlen(Alles);
     do
      {wo++;
       if(wo==laenge)
        {wo=0;
         break;
        }
      }while(Alles[wo]!='\x1B');
     return(wo);
    }
    
    int main()
    {char *Alles, *Text1, *Text2, *Fertig, *Temp;
     int wo=1,laenge, restore=0;
     double koordx,koordy;
     int zeichen=0, ende=0;
     *Alles=getchar();
    
    do
    {wo=Suchen(Alles,wo);
     strncpy(Alles, Alles, wo);
     Alles[wo]=0;
     wo=Suchen(Alles, wo);
     if(wo==0)
       {wo=strlen(Alles)+2;
        ende=1;
       }
     Umschreiben(Alles, Text1, wo);
     Temp=Text1;
     if(Temp=="E")
       {wo=Suchen(Alles,wo);
        strncpy(Alles, Alles, wo);
        Alles[wo]=0;
        wo=Suchen(Alles,wo);
        Umschreiben(Alles, Text1, wo);
        Temp = strcat( Temp , Text1 );
       }
     Text1=Temp;
     if(Temp[0]=='E'&&Temp[1]=='%'&&Temp[2]=='-'&&Temp[3]=='1')
       {Fertig = strcat( Fertig, "%! " );
       }
     if(Temp[0]=='&'&&Temp[1]=='l'&&Temp[2]=='1'&&Temp[3]=='O')
       {Fertig = strcat( Fertig, "90 rotate 1000 20 translate " );
       }
     if(Temp[0]=='&'&&Temp[1]=='l'&&Temp[2]=='0'&&Temp[3]=='O')
       {Fertig = strcat( Fertig, "800 1000 translate " );
       }
     if(Temp=="\22")
       {Fertig = strcat( Fertig, "-10 0 rmoveto " );
       }
     if(Temp[0]=='('&&Temp[1]=='1'&&Temp[2]=='9'&&Temp[3]=='U')
       {Fertig = strcat( Fertig, "/Times-Italic findfont setfont " );
        if(Text1!="")
         {zeichen=1;
         }
       }
     if(Temp[0]=='('&&Temp[1]=='s'&&Temp[2]=='0'&&Temp[3]=='B')
      {Fertig = strcat( Fertig, "/Times-Roman findfont setfont " );
       strcpy(Text1,Text1+4);
       if(Text1!="")
         {zeichen=1;
         }
      }
     if(Temp[0]=='('&&Temp[1]=='s'&&Temp[2]=='3'&&Temp[3]=='B')
       {Fertig = strcat( Fertig, "/Times-Bold findfont setfont " );
        strcpy(Text1,Text1+4);
        if(Text1!="")
         {zeichen=1;
         }
       }
     if(Temp=="(s1P")
       {sprintf(Temp,"%f",koordx);
        Fertig = strcat( Fertig, Temp);
        Fertig = strcat( Fertig, " " );
        sprintf(Temp,"%f",koordy);
        Fertig = strcat( Fertig, Temp);
        Fertig = strcat( Fertig, " moveto " );
        Text1=" ";
       }
     if(Temp=="(s16602T")
       {Text1=" ";
       }
     if(Temp[0]=='('&&Temp[1]=='s')
       {laenge=strlen(Temp);
        strncpy(Text2, Text1, laenge);
        strcpy(Text1,Text1+2);
        laenge=strlen(Text1);
        strncpy(Text1, " ", laenge-1);
        if(Text2=="V")
          {Fertig = strcat( Fertig, "gsave " );
           Fertig = strcat( Fertig, Text1);
           Fertig = strcat( Fertig, " scalefont setfont " );
           restore=1;
         }
       }
     if(Text1[0]=='*'&&Text1[1]=='p')
       {laenge=strlen(Temp);
        strncpy(Text2, Text1, laenge);
        strcpy(Text1,Text1+2);
        laenge=strlen(Text1);
        strncpy(Text1, " ", laenge-1);
        if(Text2=="X")
          {
             koordx=atof(Text1);
             koordx=(koordx/11,77)*(-1);
    
          }
        if(Text2=="Y")
          {
             koordy=atof(Text1);
             koordy=(koordy/11,77)*(-1);
    
          }
       }
     if(zeichen==1)
       {zeichen=0;
        Fertig = strcat( Fertig, "('" );
        Fertig = strcat( Fertig, Text1 );
        Fertig = strcat( Fertig, "') show " );
        if(restore==1)
          {Fertig = strcat( Fertig, "grestore " );
           restore=0;
          }
       }
     laenge=strlen(Alles);
    }while(ende!=1);
     putchar(*Fertig);
     return 0;
    }
    

    danke schon vorher!!

    mfg saroll



  • Also ich sehe ne Menge Fehler, die zu einem Bufferoverflow führen können.

    Merke:

    • Wenn bei einer Funktion aus string.h ein n im Funktionsnamen steht und nur bis zu einer maximalen Anzahl an Zeichen etwas macht, dann muss man immer darauf achten das Stringendezeichen zu setzen!
    • Wenn du eine endbedingte Schleife ( do{}while(); ) verwendest, dann überlege zuerst, ob der Code darin wirklich in jedem Fall mindestens einmal durchgeführt werden soll oder ob es eventuell zu unerwarteten Verhalten kommt oder gar zu Fehlern!
    • Achte darauf, dass auch Speicher reserviert ist für das was du in einer Variablen speichern willst!

    Der letzte Punkte bezieht sich auf:

    ...
    char *Alles, *Text1, *Text2, *Fertig, *Temp;
    ...
    

    Das sind nur Zeiger. Sie verweisen aber auf keinen reservierten Speicher. Entweder du änderst es auf feste Char-Arrays oder du reservierst dir den Speicher mit malloc(). Wobei ich dir eher zu Ersterem raten würde.

    Beispiel:

    char Alles[1024];
    

    Edit: Da war ein Smily, wo keiner sein sollte 😉



  • aber ich weiß nicht wie groß die sein können...
    is ja immer anders...
    kann ich ein maximales limit an zeichen hinschreiben??
    gibt es sowas überhaupt??

    tut mir leid wegen den fragen aber ich hab bis jetzt nur c++ programmiert
    danke
    saroll 🤡



  • Wenn die Länge variable sein soll, dann musst du malloc() verwenden. Wenn du allerdings weißt, dass maximal so und so viel Zeichen kommen können, dann verwende am besten diesen Wert (der Einfachheit halber).

    Du liest deine Daten ja mit getchar() ein. Du weißt aber schon, dass diese Funktion nur 1 Zeichen liest. In welcher Form stehen eigentlich deine Daten zur Verfügung?



  • boa, ich komm echt nicht weiter *gg*
    kann es sein das fast alle funktionen nur mit zeigern laufen??
    wie kann ich das machen wenn ich nur feste char-arrays hab??
    kannst du mir nicht noch nen schubs in die richtige richtung geben??

    danke
    saroll



  • Du musst an deinen Funktionen und dem Quellcode (bis auf die anderen Fehler, die ich oben schon erwähnt hab) nichts ändern, wenn du feste Arrays nimmst.



  • Compiler schrieb:

    [C++Fehler] lis2psc.cpp(50): Lvalue required.

    das steht bei jeder funktion...
    *voll traurig*

    mfg saroll



  • Quellcode. Aber bitte nicht den ganzen. Nur deine Variablen, den Aufruf deiner ersten Funktion, die nicht geht und die Funktion selbst.



  • char Alles[1000], Text1[100], Text2[100], Fertig[1000], Temp[100];
    
    Temp = strcat( Temp , Text1 );
    


  • Lass das "Temp =" weg, auch bei den anderen Funktionen, die mit den Strings arbeiten.



  • Alles=getchar();
    

    wie kann ich das ändern??



  • so, ich hab das jetzt geändert wie du gesagt hast (oder wie ich es verstanden habe) ich poste hier mal den source, kannst du mir wieder einen "schubser" geben?? es ist glaub ich wieder ein übertrittsfehler passiert...

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    void Umschreiben(char *Alles, char *Text1, int wo)
    {strncpy(Text1,Alles, wo);
     Text1[wo]=0;
     strcpy(Alles,Alles+wo);
    }
    
    int Suchen(char *Alles, int wo)
    {int laenge=strlen(Alles);
     do
      {wo++;
       if(wo==laenge)
        {wo=0;
         break;
        }
      }while(Alles[wo]!='\x1B');
     return(wo);
    }
    
    int main()
    {char Alles[10000], Text1[100], Text2[100], Fertig[10000], Temp[100], *Einlesen;
     int wo=1,laenge, restore=0;
     double koordx,koordy;
     int zeichen=0, ende=0;
     *Einlesen=getchar();
     strcpy(Alles, Einlesen);
     wo=Suchen(Alles,wo);
     if(wo!=0)
     {
    do
    {wo=Suchen(Alles,wo);
     strncpy(Alles, Alles, wo);
     Alles[wo]=0;
     wo=Suchen(Alles, wo);
     if(wo==0)
       {wo=strlen(Alles)+2;
        ende=1;
       }
     Umschreiben(Alles, Text1, wo);
     strcpy(Temp,Text1);
     if(Temp=="E")
       {wo=Suchen(Alles,wo);
        strncpy(Alles, Alles, wo);
        Alles[wo]=0;
        wo=Suchen(Alles,wo);
        Umschreiben(Alles, Text1, wo);
        strcat( Temp , Text1 );
       }
     strcpy(Text1,Temp);
     if(Temp[0]=='E'&&Temp[1]=='%'&&Temp[2]=='-'&&Temp[3]=='1')
       {strcat( Fertig, "%! " );
       }
     if(Temp[0]=='&'&&Temp[1]=='l'&&Temp[2]=='1'&&Temp[3]=='O')
       {strcat( Fertig, "90 rotate 1000 20 translate " );
       }
     if(Temp[0]=='&'&&Temp[1]=='l'&&Temp[2]=='0'&&Temp[3]=='O')
       {strcat( Fertig, "800 1000 translate " );
       }
     if(Temp=="\22")
       {strcat( Fertig, "-10 0 rmoveto " );
       }
     if(Temp[0]=='('&&Temp[1]=='1'&&Temp[2]=='9'&&Temp[3]=='U')
       {strcat( Fertig, "/Times-Italic findfont setfont " );
        if(Text1!="")
         {zeichen=1;
         }
       }
     if(Temp[0]=='('&&Temp[1]=='s'&&Temp[2]=='0'&&Temp[3]=='B')
      {strcat( Fertig, "/Times-Roman findfont setfont " );
       strcpy(Text1,Text1+4);
       if(Text1!="")
         {zeichen=1;
         }
      }
     if(Temp[0]=='('&&Temp[1]=='s'&&Temp[2]=='3'&&Temp[3]=='B')
       {strcat( Fertig, "/Times-Bold findfont setfont " );
        strcpy(Text1,Text1+4);
        if(Text1!="")
         {zeichen=1;
         }
       }
     if(Temp=="(s1P")
       {sprintf(Temp,"%f",koordx);
        strcat( Fertig, Temp);
        strcat( Fertig, " " );
        sprintf(Temp,"%f",koordy);
        strcat( Fertig, Temp);
        strcat( Fertig, " moveto " );
        strcpy(Text1," ");
       }
     if(Temp=="(s16602T")
       {strcpy(Text1," ");
       }
     if(Temp[0]=='('&&Temp[1]=='s')
       {laenge=strlen(Temp);
        strncpy(Text2, Text1, laenge);
        Text2[laenge]=0;
        strcpy(Text1,Text1+2);
        laenge=strlen(Text1);
        strncpy(Text1, " ", laenge-1);
        Text1[laenge-1]=0;
        if(Text2=="V")
          {strcat( Fertig, "gsave " );
           strcat( Fertig, Text1);
           strcat( Fertig, " scalefont setfont " );
           restore=1;
         }
       }
     if(Text1[0]=='*'&&Text1[1]=='p')
       {laenge=strlen(Temp);
        strncpy(Text2, Text1, laenge);
        Text2[laenge]=0;
        strcpy(Text1,Text1+2);
        laenge=strlen(Text1);
        strncpy(Text1, " ", laenge-1);
        Text1[laenge-1]=0;
        if(Text2=="X")
          {
             koordx=atof(Text1);
             koordx=(koordx/11,77)*(-1);
    
          }
        if(Text2=="Y")
          {
             koordy=atof(Text1);
             koordy=(koordy/11,77)*(-1);
    
          }
       }
     if(zeichen==1)
       {zeichen=0;
        strcat( Fertig, "('" );
        strcat( Fertig, Text1 );
        strcat( Fertig, "') show " );
        if(restore==1)
          {strcat( Fertig, "grestore " );
           restore=0;
          }
       }
     laenge=strlen(Alles);
    }while(ende!=1);
    }
     putchar(*Fertig);
     return 0;
    }
    

    ich hoffe ich nerve nicht 😞 😞

    mfg saroll 🤡



  • Du hast da eine Speicherverletzung drin und zwar gleich beim ersten Befehl *Einlesen=getchar();

    Einlesen zeigt irgendwohin und da möchtest du mit getchar() ein Zeichen hinschreiben. Das mag das Betriebssystem nicht!

    Anscheinend bekommst du deine Daten über die Tastatur (hab dich eigentlich schon mal gefragt, woher du deine Daten bekommst). Daher solltest du fgets() (mit stdin als Filestream) verwenden. Allerdings musst du dann noch eine Schleife um das ganze machen, da fgets() nur zeilenweise einliest. Außer du hast keinen Zeilenumbruch in deinen Daten, dann kannst du auf die Schleife verzichten.

    Dann gibt es noch was zum Vergleichen von Strings zu sagen. Einmal hab ich was gesehen da hast du eine Variable derart verglichen: var == "E"
    Das geht so leider nicht in C. Da es sich bei E ja nur um ein Zeichen handelt, brauchst du nur einfache Anführungszeichen, also 'E'.
    Dann ist mir noch aufgefallen, dass du mehrere Zeichen hintereinander extra vergleichst. So in der Art: Temp[0] == 'a' && Temp[1] == 'b' && Temp[2] == 'c' ...
    Das kannst du ganz einfach abkürzen durch ein strcmp() (vergleicht die kompletten Strings bis zum Stringendezeichen) bzw. strncmp() (vergleicht die Strings bis zu einer bestimmten Anzahl an Zeichen). Im Beispiel würde das so aussehen: strncmp(Temp, "abc", 3) == 0

    strcmp() bzw. strncmp() haben die kleine Besonderheit, dass sie 0 zurückgeben, wenn der Vergleich positiv war. Mehr über die Rückgabe findest du hier: http://www.cplusplus.com/ref/indexr.html

    Am Schluss solltest du übrigens auch ein puts() verwenden anstatt putchar() und keinen Stern vor Fertig schreiben ;).



  • AJ schrieb:

    Anscheinend bekommst du deine Daten über die Tastatur (hab dich eigentlich schon mal gefragt, woher du deine Daten bekommst). Daher solltest du fgets() (mit stdin als Filestream) verwenden. Allerdings musst du dann noch eine Schleife um das ganze machen, da fgets() nur zeilenweise einliest. Außer du hast keinen Zeilenumbruch in deinen Daten, dann kannst du auf die Schleife verzichten.

    nein, ich lese aus einer datei aus, wie mach ich das mit der schleife??
    bleibt da die eigentliche datei erhalten??

    AJ schrieb:

    Das geht so leider nicht in C. Da es sich bei E ja nur um ein Zeichen handelt, brauchst du nur einfache Anführungszeichen, also 'E'.

    Compiler schrieb:

    [C++Fehler] lis2psc.cpp(46): Cannot convert 'char' to 'char *'.

    mit 'E' gehts aber auch nicht 😞

    mfg saroll 🤡



  • Saroll schrieb:

    nein, ich lese aus einer datei aus, wie mach ich das mit der schleife??
    bleibt da die eigentliche datei erhalten??

    Dann musst du auch was mit Dateiverarbeitung machen. D. h. schau dir mal die Funktionen fopen(), fgets() und fclose() an. Die Datei bleibt natürlich erhalten ;).

    Compiler schrieb:

    [C++Fehler] lis2psc.cpp(46): Cannot convert 'char' to 'char *'.

    mit 'E' gehts aber auch nicht 😞

    mfg saroll 🤡

    Du darfst dann natürlich nicht auf Temp abprüfen, sondern musst auf *Temp abprüfen. 🙂

    Nun noch zu deiner Schleife:
    Am Anfang deines Programms musst du erstmal deine Datei öffnen (fopen()), und dann machst du deine Schleife, als Bedingung liest du die Datei ein (fgets()). fgets() liefert 0 zurück, wenn es am Dateiende ist. Und nach der Schleife schließt du die Datei wieder.

    Nach dem Öffnen nicht das Abprüfen vergessen, ob die Datei auch geöffnet werden konnte ;).



  • AJ schrieb:

    Nach dem Öffnen nicht das Abprüfen vergessen, ob die Datei auch geöffnet werden konnte .

    PFF... du überforderst mich 🤡

    was wenn bei unix die datei direkt auf den stdin draufgelegt wird??



  • Dann musst du von stdin einlesen. Da kannst du dir natürlich das Öffnen und Schließen sparen, aber das fgets() und die Schleife bleiben gleich :).



  • *heul* ich brings nicht hin *wein*
    mit c++ isses ja ganz einfach aber so?!

    *heul*



  • In C ist es auch einfach, wenn man Übung darin hat 😉

    Kleines Beispiel für die Schleife:

    ...
    while(fgets(zeile, sizeof(zeile), stdin))
    {
       printf("%s", zeile);
    }
    ...
    

    Anstatt printf() kommt natürlich dein Code ;). Mehr ist es auch nicht :).



  • und was bedeutet die schleife??
    das jedes mal eine zeile genommen wird und dann in "zeile" geschrieben wird??
    so lange bis keine zeilen mehr da sind??


Anmelden zum Antworten