buchstaben in einer datei abzählen

a) Hier:
C++:
struct probuchstabe temp[1];
brauchst du kein Array
C++:
struct probuchstabe temp;

b) Du musst die 26 structs zuerst initialiseren.
anz auf 0 setzen und beim Buchstaben was eintragen.

c) Beim Hochzählen nicht buchstabe, sondern anz mit ++ erhöhen.

d) Bei der Prozentberechnung zuerst in float casten, sonst gibts ein Kommastellenproblem.

e) Beim Sort - wenn schon - temp[0] nehmen.
Aber wie gesagt, es muss kein Array sein.

f) Auch beim Sort: Wenn du sortiert vor der Schleife nicht auf 1 setzt
(oder eine do-while-Schleife machst) wird nie was sortiert werden.
 
danke! auf das temp array wäre ich nicht so schnell gekommen...

C:
#include <stdio.h>
#include <stdlib.h>

struct probuchstabe
{
    char buchstabe;
    int anz;
    float prozent;
    char correct;
};
 
int main(int argc, char *argv[])
{
    FILE *datei;
    float buchstaben[26][3];
    int i, j;
    char c;
    float t=0;
    
    const int laenge=26;		// for bubble-sort
    int sortiert=0;			// for bubble-sort
    
    struct probuchstabe werte[26];
    struct probuchstabe temp;
    
    for(i=0; i<26; i++)
    {
		werte[i].buchstabe = 'a'+i;
    	werte[i].anz = 0;
    	werte[i].prozent = 0.0;
    	werte[i].correct = 'a';
    }
    
    temp.buchstabe = 'a';
    temp.anz = 0;
    temp.prozent = 0.0;
    temp.correct = 'a';
		
    datei = fopen(argv[1], "r");
 
    if(datei == NULL)
    {
        puts("Error");
        system("pause");
        return 1;					// 1 bei fehler; 0 bei alles OK
    }
    else
    {
        // puts("Error-Free");
    }
 
    while(!feof(datei))
    {
        c = fgetc(datei);
 
        if(c >= 'A' && c <= 'Z')
        {
            c = c - 'A' + 'a';		// große buchstaben in kleine umwandeln
        }
        if(c >= 'a' && c <= 'z')
        {
			werte[c - 'a'].anz++;		// position im array bestimmten und buchstaben raufzählen	
        }
    }
     
    // puts("End of File");
    
	for(i=0; i<26; i++)
    {
		t=t+werte[i].anz;
	}
	
	for(i=0; i<26; i++)
    {
		werte[i].prozent=(float)werte[i].anz*100/t;	// prozent berechnen
	}
	
	// bubble-sort
	while(sortiert == 0)
	{
		sortiert = 1;
		
		for(i = 0; i < laenge-1; i++)
		{
			if(werte[i].prozent < werte[i+1].prozent)
			{
				sortiert = 0;
				
				temp = werte[i];
				werte[i] = werte[i+1];
				werte[i+1] = temp;
			}
		}	
	}
		
    for(i = 0; i < 26; i++)
    {
		printf("%c\t %d\t %.3f%%\t\n", werte[i].buchstabe, werte[i].anz, werte[i].prozent);
    }
    
    fclose(datei);
    
   // deutsche Buchstabenverteilung
	werte[0].correct = 'e';
	werte[1].correct = 'n';
	werte[2].correct = 'i';
	werte[3].correct = 's';
	werte[4].correct = 'r';
	werte[5].correct = 'a';
	werte[6].correct = 't';
	werte[7].correct = 'd';
	werte[8].correct = 'h';
	werte[9].correct = 'u';
	werte[10].correct = 'l';
	werte[11].correct = 'c';
	werte[12].correct = 'g';
	werte[13].correct = 'm';
	werte[14].correct = 'o';
	werte[15].correct = 'b';
	werte[16].correct = 'w';
	werte[17].correct = 'f';
	werte[18].correct = 'k';
	werte[19].correct = 'z';
	werte[20].correct = 'p';
	werte[21].correct = 'v';
	werte[22].correct = 'j';
	werte[23].correct = 'y';
	werte[24].correct = 'x';
	werte[25].correct = 'q';
	
    printf("\n\n");
    
    // Ausgabe
    datei = fopen(argv[1], "r");
    while(!feof(datei))
    {
    c = fgetc(datei);
    printf("%c", c);
	}
 	fclose(datei);
 	
 	printf("\n\n");
 	
 	for(i = 0; i < 26; i++)
    {
		printf("%c\t %c\n", werte[i].buchstabe, werte[i].correct);
    }
	    
    printf("\n\n");
    
	system("pause");
    return 0;
}

Mein Ziele wäre jetzt: Ich habe eine Text. Von dem hab ich die nach der Analyse die Verteilung der Buchstaben. b ... 20% / r ... 12% / z ... 9% / usw.

Die Buchstabenverteilung der deutschen Sprache sieht so aus:
http://upload.wikimedia.org/wikiped...vg/800px-Buchstabenhäufigkeit_Deutsch.svg.png

Da b 20% hat kann ich davon ausgehe, dass es sich um ein e handelt.

Ich hätte mir gedacht, ich schreibe die deutsche Buchstabenhäufigkeit in meine Struktur nach der Sortierung rein. Das ich dann die Gegenüberstellung habe b ... e

Wenn ich dann den verschlüsselten Text lade und auf der Console ausgeben will, so wird b mit e ersetzt.

Nur irgendwie habe ich keine Plan wo ich am besten anfangen soll und ob mein Ansatz überhaupt richtig ist.
 
Zuletzt bearbeitet:
Warum hast du noch das float-Array buchstaben drin?

Zum Poblem:
Jetzt hast du also sortiert.

Mach als Nächstes einen String, der alle deutschen Buchstaben der Häufigkeit nach drin hat.
C++:
char haufigkeit[] = "enis";
Den Rest natürlich ergänzen.


Und jetzt stellt sich die Frage, wie genau du das zu lösen gedenkst.
Willst du
a) die wahrscheinlichste Lösung zeigen, Benutzer sagt richtig/falsch, ggf. kommt der nächstwahrscheinlichste Vorschlag...
b) mit einem Verfahren die beste Lösung ermitteln, die eventuell auch falsch sein kann -> Pech
c) ...?
 
Danke schon mal. Ich werde mich morgen weiter mit dem Thema auseinander setzen und meine Ergebnisse dann posten.
 
Hi.

Du hast also einen mit einer Caesar Chiffre verschlüsselten Text.

Dabei wird das Alphabet im Prinzip nur "verschoben". Beim Brechen der Verschlüsselung mußt du nun diese Verschiebung berechnen.

Du mußt also das Histogramm der verschlüsselten Datei mit dem Histogramm des deutschen Alphabets vergleichen. Dazu kannst du z.B. den mittleren quadratischen Fehler berechnen.

C:
/* Buchstabenhäufigkeit in Prozent für A bis Z laut http://.. */
double german[] = { 5.58,
	1.96,
	3.16,
	4.98,
	16.93,
	1.49,
  ... };

/* Buchstabenhäufigkeit in Prozent für A bis Z der Datei */
double haeufigkeit[] = ...;

/* Finde die Verschiebung bei dem der Fehler minimal wird */

double min_fehler = DBL_MAX;
int min_verschiebung = 0;
for (int verschiebung = 0; verschiebung < 26; ++verschiebung) {
  double fehler = vergleiche(german, haufigkeit, verschiebung);

  if (fehler < min_fehler) {
    ...
  }
}
Gruß
 
Zuletzt bearbeitet:
Danke soweit.
Bei meinem Ansatz habe ich jetzt die Verschiebung zum meist vorkommenden Buchstaben und dem e berechnet.

Dann sage ich bei der Ausgabe Klartext, wenn der Buchstabe zwischen A und z liegt, so soll die Verschiebung abgezogen werden.

Wenn es sich um ein Satzzeichen handelt, dann soll es 1:1 ausgegeben werden.

Jetzt habe ich die Probleme:
1) was mache ich, wenn die von A der Schlüssel abgezogen wird, so wird mir 9 ausgegeben. Normal müsste aber hinten beim Z weiter gerechnet werden.

2) Was mache ich wenn zu Z der Schlüssel addiert wird, dann komme ich in die Kleinbuchstaben rein.

3) Zwischen Groß- und Kleinbuchstaben habe ich ja noch ein paar andere Zeichen.

Ich müsste es irgendwie hinkriegen, wenn es sich um einen Großbuchstaben handelt, egal ob der Schlüssel + oder - gerechnet wird, dass ich immer in den Großbuchstaben bleibe. Eine Art Kreis.

Das selbe halt auch bei den Kleinbuchstaben.


C:
#include <stdio.h>
#include <stdlib.h>

// Stuct definieren
struct probuchstabe
{
    char buchstabe;
    int anz;
    float prozent;
    char correct;
};
 
int main(int argc, char *argv[])
{
	// Variablen definieren
    FILE *datei;
    float buchstaben[26][3];
    int i=0, j=0, x=0, y=0, count=0;
    char c;
    float t=0;
    
    const int laenge=26;	// for bubble-sort
    int sortiert=0;			// for bubble-sort
    
    struct probuchstabe werte[26];
    struct probuchstabe temp;
    
    //------------------------------------------
    
    for(i=0; i<26; i++)
    {
		werte[i].buchstabe = 'a'+i;
    	werte[i].anz = 0;
    	werte[i].prozent = 0.0;
    	werte[i].correct = 'a';
    }
    
    temp.buchstabe = 'a';
    temp.anz = 0;
    temp.prozent = 0.0;
    temp.correct = 'a';
	
	//------------------------------------------
		
    datei = fopen(argv[1], "r");
 
    if(datei == NULL)
    {
        puts("Error");
        system("pause");
        return 1;					// 1 bei fehler; 0 bei alles OK
    }
    else
    {
        // puts("Error-Free");
    }
 
    //while(!feof(datei) && count<30)
    while(!feof(datei))
    {
        c = fgetc(datei);
 
        if(c >= 'A' && c <= 'Z')
        {
            c = c - 'A' + 'a';			// große buchstaben in kleine umwandeln
        }
        if(c >= 'a' && c <= 'z')
        {
			werte[c - 'a'].anz++;		// position im array bestimmten und buchstaben raufzählen	
        }
    }
     
    // puts("End of File");
    
    // Gesamte Buchstaben berechnen
	for(i=0; i<26; i++)
    {
		t=t+werte[i].anz;
	}
	
	// Prozent berechnen
	for(i=0; i<26; i++)
    {
		werte[i].prozent=(float)werte[i].anz*100/t;
	}
	
	// bubble-sort
	while(sortiert == 0)
	{
		sortiert = 1;
		
		for(i = 0; i < laenge-1; i++)
		{
			if(werte[i].prozent < werte[i+1].prozent)
			{
				sortiert = 0;
				
				temp = werte[i];
				werte[i] = werte[i+1];
				werte[i+1] = temp;
			}
		}	
	}
	
	// Ausgabe
	/*	
    for(i = 0; i < 26; i++)
    {
		printf("%c\t %d\t %.3f%%\t\n\n\n", werte[i].buchstabe, werte[i].anz, werte[i].prozent);
    }
    */
    fclose(datei);
    
    // Schlüssel berechnen
    x=werte[0].buchstabe-'e';
    printf("Schluessel: %d\n\n", x);
    
    // Mindest Zeichen
    printf("mindest Zeichen: %d\n\n", count);
    
    // Ausgabe (Klartext)
    datei = fopen(argv[1], "r");
    while(!feof(datei))
    {
		c = fgetc(datei);
		
		if( c >= 'A' && c <= 'z' )
		{
			printf("%c", c - x );	
		}
		
		else
		{
			printf( "%c", c);
		}
	}
 	fclose(datei);
 	 		    
    printf("\n\n");
    
	system("pause");
    return 0;
}
 
Pseudocode
Code:
if(kleiner als A geworden)
    26 dazurechnen
if(größer als Z geworden)
    26 abziehen
Das Selbe für Kleinbuchstaben
 
ein Großbuchstabe ist nach ASCII ja immer kleiner als ein Kleinbuchstabe. Von daher würde ja immer was dazu gezählt werden oder?
 
C:
char encrypted = ...;

if (isalpha(encrypted)) {
  char start;

  if (islower(encrypted) {
    start = 'a';
  } else {
    start = 'A';
  }

  char decrypted = start + (encrypted - start + schlüssel) % 26;
}

Außerdem verwendet man kein feof in einer Schleife. Das funktioniert so nicht. Und fgetc gibt einen int zurück.
C:
int c;
while ((c = fgetc(datei)) != EOF) {
  ...
}
Gruß
 
Ich wollte ja meinen Code posten, hatte ich total vergessen! Das hole ich jetzt mal nach.
Er ist zwar nicht perfekt, aber er funktioniert.

C:
#include <stdio.h>
#include <stdlib.h>

// Stuct definieren
struct probuchstabe
{
    char buchstabe;
    int anz;
    float prozent;
    char correct;
};
 
int main(int argc, char *argv[])
{
	// Variablen definieren
    FILE *datei;
    float buchstaben[26][3];
    int i=0, j=0, x=0, y=0, count=50;
    char c;
    float t=0;
    
    const int laenge=26;	// for bubble-sort
    int sortiert=0;			// for bubble-sort
    
    struct probuchstabe werte[26];
    struct probuchstabe temp;
    
    //------------------------------------------
    
    for(i=0; i<26; i++)
    {
		werte[i].buchstabe = 'a'+i;
    	werte[i].anz = 0;
    	werte[i].prozent = 0.0;
    	werte[i].correct = 'a';
    }
    
    temp.buchstabe = 'a';
    temp.anz = 0;
    temp.prozent = 0.0;
    temp.correct = 'a';
	
	//------------------------------------------
		
    datei = fopen(argv[1], "r");
 
    if(datei == NULL)
    {
        puts("Error");
        system("pause");
        return 1;					// 1 bei fehler; 0 bei alles OK
    }
    else
    {
        // puts("Error-Free");
    }
 
    //while(!feof(datei) && count<30)
    while(!feof(datei))
    {
        c = fgetc(datei);
 
        if(c >= 'A' && c <= 'Z')
        {
            c = c - 'A' + 'a';			// große buchstaben in kleine umwandeln
        }
        if(c >= 'a' && c <= 'z')
        {
			werte[c - 'a'].anz++;		// position im array bestimmten und buchstaben raufzählen	
        }
    }
     
    // puts("End of File");
    
    // Gesamte Buchstaben berechnen
	for(i=0; i<26; i++)
    {
		t=t+werte[i].anz;
	}
	
	// Prozent berechnen
	for(i=0; i<26; i++)
    {
		werte[i].prozent=(float)werte[i].anz*100/t;
	}
	
	// bubble-sort
	while(sortiert == 0)
	{
		sortiert = 1;
		
		for(i = 0; i < laenge-1; i++)
		{
			if(werte[i].prozent < werte[i+1].prozent)
			{
				sortiert = 0;
				
				temp = werte[i];
				werte[i] = werte[i+1];
				werte[i+1] = temp;
			}
		}	
	}
	
	// Ausgabe
	/*	
    for(i = 0; i < 26; i++)
    {
		printf("%c\t %d\t %.3f%%\t\n\n\n", werte[i].buchstabe, werte[i].anz, werte[i].prozent);
    }
    */
    fclose(datei);
    
    // Schlüssel berechnen
    x=werte[0].buchstabe-'e';
    printf("Schluessel: %d\n\n", x);
    
    // Mindest Zeichen
    printf("mindest Zeichen: %d\n\n", count);
    
    // Ausgabe (Klartext)
    datei = fopen(argv[1], "r");
while(!feof(datei))
    {
		c = fgetc(datei);
		
		if( c >= 'A' && c <= 'z' )
		{
			if( c - x > 'z' )
			{
				printf("%c", c - x - 58 );
			}
			
			else
			{
				if( c - x < 'A' )
				{
					printf("%c", 58 + c - x );
				}
				
				else
				{
					printf("%c", c - x );
                }
			}	
		}
		
		else
		{
			printf( "%c", c);
		}
	}
 	fclose(datei);
 	 		    
    printf("\n\n");
    
	system("pause");
    return 0;
}


Folgenden Text gilt es zu übersetzen:

MxE SDqsAD _myEm quzqE YADsqzE mGE GzDGtusqz `DmqGyqz qDImotFq, rmzp qD Euot uz Equzqy NqFF LG quzqy GzsqtqGqDqz azsqLuqrqD HqDImzpqxF. QD xms mGr Equzqy BmzLqDmDFus tmDFqz ^Gqowqz Gzp Emt, Iqzz qD pqz WABr quz Iqzus tAn, Equzqz sqIAqxnFqz, nDmGzqz, HAz nAsqzrAqDyusqz bqDEFqurGzsqz sqFquxFqz NmGot, mGr pqEEqz TAqtq Euot puq NqFFpqowq, LGy smqzLxuotqz ZuqpqDsxquFqz nqDquF, wmGy zAot qDtmxFqz wAzzFq. _quzq Huqxqz, uy bqDsxquot LG Equzqy EAzEFusqz ayrmzs wxmqsxuot pGqzzqz Nquzq rxuyyqDFqz uty tuxrxAE HAD pqz MGsqz.

"cmE uEF yuF yuD sqEotqtqz?", pmotFq qD. QE ImD wquz `DmGy. _quz fuyyqD, quz DuotFusqE, zGD qFImE LG wxquzqE YqzEotqzLuyyqD, xms DGtus LIuEotqz pqz HuqD IAtxnqwmzzFqz cmqzpqz. GqnqD pqy `uEot, mGr pqy quzq mGEquzmzpqDsqBmowFq YGEFqDwAxxqwFuAz HAz `GotImDqz mGEsqnDquFqF ImD - _myEm ImD ^quEqzpqD - tuzs pmE Nuxp, pmE qD HAD wGDLqy mGE quzqD uxxGEFDuqDFqz fquFEotDurF mGEsqEotzuFFqz Gzp uz quzqy tGqnEotqz, HqDsAxpqFqz ^mtyqz GzFqDsqnDmotF tmFFq. QE EFqxxFq quzq Pmyq pmD, puq yuF quzqy \qxLtGF Gzp quzqD \qxLnAm HqDEqtqz, mGrDqotF pmEmw Gzp quzqz EotIqDqz \qxLyGrr, uz pqy utD smzLqD azFqDmDy HqDEotIGzpqz ImD, pqy NqEotmGqD qzFsqsqztAn.

SDqsADE Nxuow DuotFqFq Euot pmzz LGy RqzEFqD, Gzp pmE FDGqnq cqFFqD - ymz tAqDFq ^qsqzFDABrqz mGr pmE RqzEFqDnxqot mGrEotxmsqz - ymotFq utz smzL yqxmzotAxuEot. "cuq ImqDq qE, Iqzz uot zAot quz Iqzus IquFqDEotxuqrq Gzp mxxq ZmDDtquFqz HqDsmqEEq", pmotFq qD, mnqD pmE ImD smqzLxuot GzpGDotrGqtDnmD, pqzz qD ImD sqIAqtzF, mGr pqD DqotFqz _quFq LG Eotxmrqz, wAzzFq Euot mnqD uz Equzqy sqsqzImqDFusqz fGEFmzp zuotF uz puqEq Xmsq nDuzsqz. YuF IqxotqD WDmrF qD Euot mGot mGr puq DqotFq _quFq ImDr, uyyqD IuqpqD EotmGwqxFq qD uz puq ^Gqowqzxmsq LGDGqow. QD HqDEGotFq qE IAtx tGzpqDFymx, EotxAw puq MGsqz, Gy puq LmBBqxzpqz Nquzq zuotF Eqtqz LG yGqEEqz, Gzp xuqw qDEF mn, mxE qD uz pqD _quFq quzqz zAot zuq sqrGqtxFqz, xquotFqz, pGyBrqz _otyqDL LG rGqtxqz nqsmzz.

"Mot SAFF", pmotFq qD, "ImE rGqD quzqz mzEFDqzsqzpqz NqDGr tmnq uot sqImqtxF! `ms mGE, `ms quz mGr pqD ^quEq. Puq sqEotmqrFxuotqz MGrDqsGzsqz Euzp Huqx sDAqwqD, mxE uy qusqzFxuotqz SqEotmqrF LG TmGEq, Gzp mGwqDpqy uEF yuD zAot puqEq \xmsq pqE ^quEqzE mGrqDxqsF, puq _ADsqz Gy puq fGsmzEotxGqEEq, pmE GzDqsqxymqwusq, EotxqotFq QEEqz, quz uyyqD IqotEqxzpqD, zuq mzpmGqDzpqD, zuq tqDLxuot IqDpqzpqD yqzEotxuotqD bqDwqtD. PqD `qGrqx EAxx pmE mxxqE tAxqz!" QD rGqtxFq quz xquotFqE VGowqz Anqz mGr pqy NmGot; EotAn Euot mGr pqy ^Gqowqz xmzsEmy zmqtqD LGy NqFFBrAEFqz, Gy pqz WABr nqEEqD tqnqz LG wAqzzqz; rmzp puq vGowqzpq _Fqxxq, puq yuF xmGFqD wxquzqz Iquwqz \GqzwFotqz nqEqFLF ImD, puq qD zuotF LG nqGDFquxqz HqDEFmzp; Gzp IAxxFq yuF quzqy Nquz puq _Fqxxq nqFmEFqz, LAs qE mnqD sxquot LGDGqow, pqzz nqu pqD NqDGqtDGzs GyIqtFqz utz WmqxFqEotmGqD.
 
Zuletzt bearbeitet:
Zurück