Logikproblem



  • Du hast eine Datei "testat.c" mit 155 Zeilen zu je 81 Zeichen?
    Wenn nicht solltest du
    - Zeichen[81] vergrößern
    - bis z<strlen() verschlüsseln
    - nicht auf <=154 sondern auf EOF oder feof() testen.

    Schau dir mal die ctype.h an. Da gibt es Funktionen wie isalpha(), isupper()

    Das

    for(c=0;c<=25;c++) // Die Schleife geht das Array Buchanz respektive das Alphabet
    { if((Zeichen[b]==('A'+c)) || (Zeichen[b]==('a'+c))) //If-Konstrukt wertet den Inhalt des Char-Arrays aus. Abhängig vom Inhalt wird der entsprechende Zähler für die Buchstaben erhöht.
       (Buchanz[c])++;
    }
    

    wird zu

    if(isalpha(Zeichen[b])) 
    { (Buchanz[toupper(Zeichen[b])-'A'])++;
    }
    

    Und soweit muss man auch nicht einrücken. Da geht auch die Übersicht verloren.



  • Ein Ausdruck wie

    Schluessel[z]-26;
    

    ist relativ sinnfrei.

    Wobei die ganze Schleife drumherum der Übeltäter ist.

    Was macht das hier ?

    while (Schluessel [z]>=123)  // Was ist 123?
    {  Schluessel[z]-26;          // da passiert .... nichts
    }                             // und dann bleibt Schluessel [z] >= 123 -> Endlosschleife
    


  • Hey DirkB,

    das mit der Endlosschleife hat mir mittlerweile auch schon ein Freund gesagt. Die 123 ist das kleine z im ASCII-Code die gelesenen Buchstaben sollen im ASCII-Code verschoben werden. Die while-Schleife sorgt dafür das der durch das verschieben entstandene Wert nicht außerhalb des Alphabets im ASCII-Code liegt. Das ganze ist so gedacht das wenn das Z erreicht ist es wieder bei A losgeht. Mir hat mittlerweile ein Kommulitone der Master Software Engineering studiert (sprich etwas mehr Ahnung von C-Programmierung hat) schon weiter geholfen aber er konnte trotzdem nicht herraus finden warum das Program ein paar Zeilen lang korrekt arbeitet und dann abstürzt. Hier eine aktuellere Version. Ich danke dir schonmal jetzt für die ersten Tipps und für noch hoffentlich folgende schon mal im vorraus.

    #include <conio.h>
    #include <stdio.h>
    #include <string.h>
    
    void statistik(int ges, int BUA [] ,double STA [])
    {
         int g;
         for(g=0;g<=25;g++)// Geht das Feld mit den Anzahlen der einzelnen Buchstaben durch.
                   {
                         STA[g]=((double)BUA[g]/ges)*100; //Berechnet den prozentualen Anteil eines Buchstabens an der Gesamtheit der Zeichen.                                       
                   }
    
    }
    
    void verschluesseln(char Schluessel [], int of, int BUAV [], FILE *ausi ) // Gelesenen String reinholen, Offset reinholen, Zählfeld reinholen, Pointer für ausgabe reinholen
    {
         int d,e,z;
         of =of%26;
    
        for(z=0;z<strlen(Schluessel);z++) //eingelesene Zeile durchgehen
    
            {    
                char c =  Schluessel[z];
                printf("%c %i\n", c, c);
                       if(Schluessel[z]>='a' && Schluessel[z]<='z') //Wenn das Zeichen ein Kleinbuchstabe ist Zähle offset dazu und ziehe so lange 26 ab bis das Zeichen wieder im Alphabet landet.
    
                                   {
                                            Schluessel[z]=Schluessel[z]+of;
                                            if (Schluessel [z]>='z')
                                                  {
                                                      Schluessel[z]=Schluessel[z]-of;           
    
                                                  }
                                   }else if (Schluessel[z]>='A' && Schluessel[z]<='Z') //Selbes wie oben nur für Großbuchstaben
                                         {
                                            Schluessel[z]=Schluessel[z]+of;
                                            if (Schluessel [z]>='Z')
                                                  {
                                                      Schluessel[z]=Schluessel[z]-of;           
                                                  }                      
    
                                         }
    
            }
        fputs(Schluessel,ausi); //verschlüsselte Zeile in Datei schreiben   
        for(d=0;d<=strlen(Schluessel);d++) // Die Schleife geht das Array Schlüssel durch respektive die eingelesene Zeile.
    			{                    
                        for(e=0;e<=25;e++) // Die Schleife geht das Array BUAV durch respektive das Alphabet
                                {
                                           if(Schluessel[d]==('A'+e) || Schluessel[d]==('a'+e)) //If-Konstrukt wertet den Inhalt des Char-Arrays aus. Abhängig vom Inhalt wird der entsprechende Zähler für die Buchstaben erhöht.
                                           {
                                      //             (BUAV[e])++; 
    
                                           }    
                            }
                }
    }
    
    void sortieren(int BA [], double STA [], char BU []) //BA= Buchstabenanzahl , STA = Statistik, BU = Buchstaben
    {
         int  tmpi=0,i,j;
         double tmpd=0;
         char tmpc='a';
    
        for (i=0; i<26; i++)
            {
                  for(j=0;j<26-i;j++)
    
                      {
                                     if((BA[j] < BA[j+1])&&(j+1<=26))
                                               {
                                                     tmpi=BA[j];   //BA an der Stelle j wird in tmpi gesichert.
                                                     BA[j]=BA[j+1];//BA an der Stelle j gleich BA an der Stelle j+1
                                                     BA[j+1]=tmpi; //BA an der Stelle j+1 gleich tmpi
    
                                                     tmpd=STA[j];  //Siehe oben
                                                     STA[j]=STA[j+1];
                                                     STA[j+1]=tmpd;
    
                                                     tmpc=BU[j];  //Siehe oben
                                                     BU[j]=BU[j+1];
                                                     BU[j+1]=tmpc;                                                                                       
                                               }                                          
                      }                    
            }
    }
    
    int main (void)
    
    {
    
    char Zeichen [81], Buchstaben[26], Buchstabenv [26]; //Hier werden die gelesenen Werte aus den Zeilen eingetragen
    int Buchanz [26],Buchanzv [26],z=0,Gesamt=0,off=0,a,b,c,d,f,fu;
    double Stati[26],Stativ[26];
    FILE *ausgabe1,*ausgabe2, *eingabe;
    eingabe = fopen ("testat.c", "rt");
    ausgabe1 =fopen ("verschluesselt.c","wt");
    ausgabe2 =fopen ("ergebnisse.c","wt");
    for(fu=0;fu<=25;fu++)
        {
           Buchanz[fu]=0;
           Buchanzv[fu]=0;
           Stati[fu]=0;
           Stativ[fu]=0;
           Buchstaben[fu]='a'+fu;
           Buchstabenv[fu]='a'+fu;            
        }
    for(f=0;f<=80;f++)
        {
            Zeichen[f]='a';
        }        
    
    printf("Geben Sie den Offset ein\n");
    fflush(stdin);
    scanf("%i", &off);
    
    	printf("\ntest");
    
    	while (feof("testat.c"))
    		{
    
    	printf("\ntest1");
    
    			fgets(Zeichen,sizeof(Zeichen),eingabe); //Eine Zeile aus testat.c wird über den Pointer eingabe eingelesen und in Zeichen abgelegt
    
    	printf("\ntest2");
    
    			for(b=0;b<strlen(Zeichen);b++) // Die Schleife geht das Array Zeichen durch respektive die eingelesene Zeile.
    			{                    
                        for(c=0;c<=25;c++) // Die Schleife geht das Array Buchanz respektive das Alphabet
                                {
                                           if((Zeichen[b]==('A'+c)) || (Zeichen[b]==('a'+c))) //If-Konstrukt wertet den Inhalt des Char-Arrays aus. Abhängig vom Inhalt wird der entsprechende Zähler für die Buchstaben erhöht.
                                           {
                                                   (Buchanz[c])++; 
    
                                           }          
    
                                }
    
                }
    			Gesamt=Gesamt+strlen(Zeichen);
    
                verschluesseln(Zeichen,off,Buchanzv,ausgabe1);
    			z++; //Erhöht die Zählvariable die die Zeilen durchgeht.
    
    		}
    
                statistik(Gesamt,Buchanz,Stati);
                statistik(Gesamt,Buchanzv,Stativ);
                sortieren(Buchanz, Stati, Buchstaben);
                sortieren(Buchanzv,Stativ,Buchstabenv);
                printf("Statistik VOR dem Verschlüsseln: %i% Zeichen\n", Gesamt);
                for(a=0;a<=25;a++)
    
                       {
                         printf("%c%/%c% :   %i% :    %.2lf%\n", (Buchstaben[a]+32),Buchstaben[a],Buchanz[a],Stati[a]);
    
                       }
                printf("Statistik NACH dem Verschlüsseln: %i% Zeichen\n", Gesamt);
                for(d=0;d<=25;d++)
                {    
                     printf("%c%/%c% :   %i% :    %.2lf%\n",Buchstabenv[d]+32,Buchstabenv[d],Buchanzv[d],Stativ[d]);
                }
    
    //printf("%i", Gesamt);
    getchar();
    
    }
    


  • Valrok schrieb:

    while (feof("testat.c"))

    Mach dich mal über feof schlau. Z.B. hier: [url]http://www.cplusplus.com/reference/clibrary/cstdio/feof/
    [/url]
    Es wäre sehr hilfreich wenn du deinen Fehler besser beschreibst als "Program stürzt ab".
    - Welche Ausgaben kommen noch?
    - Bei welcher Zeile passiert das?
    - Wie groß ist dein Offset?
    - Wie sieht deine "testat.c" aus?

    Benutze einen Debugger oder mache mehr Zwischenausgaben (mit printf) in deinem Programm.
    Z.B. in verschluesseln

    printf("verschluesseln start : %4d <%s>\n", of, Schluessel);
    for(g=
    {....
    }
    printf("verschluesseln fertig: %4d <%s>\n", of, Schluessel);
    fputs(Schluessel,...
    

    Dann siehst du wo das Program abstürzt.

    Du solltest immer noch das Array zeichen vergrößern. Sei nicht sparsam, 1000 Zeichen ist ok.

    Und deine Statistik zum Zeichen zählen ist grauenvoll.



  • Ich hab jetzt nochmal ein bisschen rumprobiert und hab versucht micht mit dem Debugger vertraut zu machen. Bis zu dem Punkt wo ich verschlüssele klappt alles nur sobald ich dann einen schritt weiter machen lasse sprich die Statistikfunktion angehe kommt folgende Meldung. An Access Violation (Segmentation Fault) raised in your program.

    Ich hoffe das sagt dir jetzt mehr. Und zu dem "stürzt ab" kann ich leider nicht mehr sagen. Es kommt einfach eine Meldung von Windos das das Program ein Problem hat und das nach einer Lösung gesucht wird die aber nicht gefunden wird.^^



  • Eine Access Violation ist eine Zugriffsverletzung. Das Programm versucht auf Speicher zuzugreifen, dder ihm nicht gehört.

    Wenn ich das richtig sehe stürzt dein Programm beim sortieren ab.

    Wenn j die 25 erreicht (bei i=0) greifst du auf das Element BA[j+1] zu (das ist dann BA[26]). Dieses Element existiert nicht: -> Zugriffsverletzung!

    Du kannst beim Debugger auch Einzelschritte machen und Breakpoints setzten.
    Da kommst du doch automatisch an die Stelle, an der es kracht.



  • So ich bin das ganze mit dem Debugger durchgegangen.

    Als erstes lass ich das Program bis Zeile 154, sprich bis das ganze verschlüsseln abgeschlossen ist alleine laufen und bis dahin kommt keine Beschwerde.

    Dann klick mich mit Next Step Stück für Stück durch.

    Dann bin ich in etwa bei dem Stand.

    statistik(Gesamt,Buchanz,Stati);
                statistik(Gesamt,Buchanzv,Stativ);
                sortieren(Buchanz, Stati, Buchstaben);
                sortieren(Buchanzv,Stativ,Buchstabenv);
                printf("\n");
                printf("Statistik VOR dem Verschlüsseln: %i% Zeichen\n", Gesamt);
                for(a=0;a<=25;a++)
    
                       {
                         printf("%c%/%c% :   %i% :    %.2lf%\n", (Buchstaben[a]+32),Buchstaben[a],Buchanz[a],Stati[a]);
    
                       }
                printf("Statistik NACH dem Verschlüsseln: %i% Zeichen\n", Gesamt);
                for(d=0;d<=25;d++)
                {    
                     printf("%c%/%c% :   %i% :    %.2lf%\n",Buchstabenv[d]+32,Buchstabenv[d],Buchanzv[d],Stativ[d]);
                }
    
    //printf("%i", Gesamt);
    getchar();
    
    }
    

    Ich stehe mit dem Cursor vor der ersten Statistikfunktion. Die Statistikfunktionen sowie die Sortierfunktionen geht er ohne meckern durch. Das printf ("\n") ist auch kein Problem. Dann ist es soweit das ich mit dem Cursor bei

    printf("Statistik VOR dem Verschlüsseln: %i% Zeichen\n", Gesamt);
    

    stehe.
    So wenn ich jetzt auf Next Step klicke kommt der Fehler. Der Fehler kommt bei dem print.



  • Die Formatangaben von printf werden mit einem %-Zeichen eingeleitet. Wenn der richtige Buchstabe für die Formatangabe kommt ist die Angabe fertig.
    Wenn du das % Zeichen mit printf ausgebenwillst, musst du es doppelt angeben. "%%"

    Ich weiß nicht wie dein System auf "% " reagiert.

    Und was willst du mit

    printf("%c%/%c% :   %i% :    %.2lf%\n", (Buchstaben[a]+32),Buchstaben[a],Buchanz[a],Stati[a]);
    

    erreichen?

    Das:

    printf("%c : %4d : %4d  :    %.2f%%\n", a+'A', Buchstaben[a], Buchanz[a], Stati[a]);
    

    ?



  • Der Code sollte folgendes ausgeben.

    E/e : 468 : 9.49%

    So sollte das aussehen und dann halt für alle Buchstaben.



  • Mittlerweile läuft alles wie es soll noch mal danke an dich DirkB für deine Hilfe.

    Ich hab jetzt herausgefunden woher der der Error kam.

    Es lag wirklich dran das ich bei

    printf("Statistik VOR dem Verschlüsseln: %i% Zeichen\n", Gesamt);
    

    ein %-Zeichen zu viel hatte. Dann waren noch ein paar Kleinigkeiten drin die keinen Sinn gemacht haben aber jetzt auch behoben sind.


Anmelden zum Antworten