txt datei einlesen und bearbeiten in c++



  • Ja das lässt sich wirklich kompilieren, ohne Warnings oder sonst was. Wie gesagt mein Prob ist gerade, dass es mit der Berechnung der einzelnen Prozente nicht hinhaut. Alles andere geht ja soweit.



  • na dann such mal std::accumulate oder rechne das zeugs per hand zusammen und dann nimm eben immer aktuelle_buchstabe_anz/float(gesamt_anzahl)
    und schon geht alles genau so, wie du dir das vorgestellt hast...
    musst nur darauf achten, dass du es so nicht als integer abspeicherst ^^
    sondern entweder erst noch *100 rechnest oder gleich als float speicherst / ausgibst

    bb



  • Mh irgendwie weiss ich nicht genau wo/wie ich da jetzt ansetzen soll. Hab mir z.B. die Accumulate Sachen mal angeschaut, aber bin mir nicht sicher wo ich das genau reinpacken muss.



  • Hab gerade beim debuggen gesehen, dass der Counter im Prinzip 4 Arrays anlegt. In denen steht dann entsprechend die Häufigkeit der Buchstaben.

    Das Ganze sieht laut Debugger so aus:

    [0](97 'a' 1)
    [1](98 'b' 1)
    [2](99 'c' 1)
    [3](100 'd' 1)
    

    So...wenn er dann ein mal mal durchgelaufen ist sieht es dann im Prinzip gleich aus, lediglich die letzte zahlenreihenfolge schaut dann so aus:

    4
    3
    2
    1

    Das stimmt auch alles. Nur wie komme ich da jetzt dran an diese Inhalte um meine prozentrechnung durchführen zu können. Und zudem möglichst einfach ohne großartige Umwandlungen oder Vectoren. Gibt es da eine Möglichkeit?



  • so ungeschickt kann man sich doch gar nich mehr anstellen -.-

    A 4
    B 3
    C 2
    D 1

    4+3+2+1 = 10
    P(A) = 4/10 = 40%
    P(B) = 3/10 = 30%
    P(C) = 2/10 = 20%
    P(D) = ...

    bb



  • Wenn der Inhalt der .txt fest wäre könnte man das so machen, ansonsten darf man auch wieder frickeln ^^



  • map<char, unsigned int>::iterator it=counter.begin();
          while(it!=counter.end())
          {
             cout << it->first << ":" << it->second << " - " << (it->second*100)/cgesamt << endl;
             it++;
          }
    


  • du hast doch nu ne map, wo alles drin steht, was du brauchst... -.-

    maps kann man auch (mit iteratoren) durchgehen und so die summe aus allen zeichen bilden - alternativ könnte man auch gleich mitzählen, aber darin seh ich keinen vorteil...
    und schon bist du fertig...

    bb



  • So, ich habs jetzt noch mal anders aufgezogen. Was klappt ist die Ausgabe der Buchstaben mit den Prozentwerten. Jedoch werden die Zahlen und Zeichen noch nicht richtig mit einberechnet. Hat jemand eine Idee wie ich das am besten mit integrieren kann? Hier mal mein Quellcode:

    int main(int argc, char *argv[])
    {
    	FILE *datei;
    	char str[50];
    	int numclosedfiles = _fcloseall();
    
        cout << "++++++++++++ Willkommen ++++++++++++";
    	cout << "\n";
    	cout << "\n";
    	cout << "Bitte geben Sie den Namen der Datei ein, die Sie jetzt gerne oeffnen wollen\n";
    	cout << "\n";
    	cin >> str;	
    	cout << "\n";
    	cout << "Sie haben vor folgende Datei zu oeffnen: " << str;
    	cout << "\n";
    
    // Datei lesen, falls nicht möglich Versuch gescheitert 
    // Ausgabe wird erzeugt, dass die Datei nicht geöffnet werden konnte 
    
    	fopen_s(&datei, str, "r");
    	if(datei) 
    	{ 
    		cout << "Die Datei wurde erfolgreich geoeffnet!\n";
    		cout << "\n";		
    		map<char, unsigned int> counter;
    		locale locale;
    		char h;		
    		char textlength; // Einlesen der gesamten Textlänge
    		char characters; // entsprechend einlesen der einzelnen Buchstaben
    		char c; // für das einlesen eines einzelnen Zeichensint 
    		char strDigi;
    		double percent = 0.0; // Notwendig für die Berechnung und Darstellung der % Werte		
    
    		for (h = 0; h < 27; ++h) {
    			counter[h] = 0;
    		}
    		// Setzt das Feld auf Null, Vorbeugung		
    		textlength = 0;
    
    		// Nun in einer while Schleife die einzelnen Zeichen für Zeichen durchgehen
    		// inklusive hochzähle
    
    	/*
    		ifstream input(str);
    		char tmp;
    		while( input.get(tmp) ) 
    		{ 
    			char c = tolower(tmp, locale); 
    			++counter[c];
    		}
    			for_each(counter.begin(), counter.end(), &printCounter);
    	*/	
    		ifstream input(str);
    		while( input.get(c) ) 
    		{ 
    			++textlength;
    			if (toupper(c)){
    				++counter[c-'A'];
    			}
    			else if(tolower(c)){
    				++counter[c-'a'];
    			}
    			/*
    			else if (isdigit(c){
    				int isAdigi;
    				isAdigi = atoi (strDigi);
    				++counter[c-strDigi];
    			}
    			*/
    		}
    		for_each(counter.begin(), counter.end(), &printCounter);
    
    		characters = textlength - counter[c];
    
    		printf("Laenge des Textes: %i \n", textlength);
    		printf("Anzahl der Buchstaben: %i \n", characters);
    		printf("Sonstige Zeichen: %i", counter);
    
    		cout << "\n";
    
    		for(h =0; h < 26; h++) {
    			percent = (double) counter[h] / (double)characters * 100.0;
    			printf("%4c %9i %9.2f %%\n", ('A' + h), counter[h], percent);
    		}
    


  • Warum kein C++?



  • Ich fand den Weg jetzt eigentlich nicht schlecht, es sei denn du hast / kannst mir eine bessere Alternative zeigen?! 🙂



  • Kann ich, nach meiner Fahrstunde.



  • Ich bin gespannt 🙂



  • da mir auch gerad langweilig ist, wie wärs damit:

    typedef std::map<char, unsigned int> Tcounter;
    Tcounter counter;
    std::ifstream input("dateiname.txt"); 
    while( input.get(tmp) ) 
    { 
       char c = tolower(tmp, std::locale()); 
       ++counter[c]; 
    }
    
    unsigned int sum(0);
    for(Tcounter::const_iterator i(counter.begin()), e(counter.end()); i != e; ++i)
    {
      sum += i->second;
    }
    
    for(Tcounter::const_iterator i(counter.begin()), e(counter.end()); i != e; ++i)
    {
      float percent = i->second/sum;
      cout << '[' << i->first << "]: " << percent*100 << '%' << endl;
    }
    

    vermutlich könnte man noch std-algorithmen für die beiden schleifen nehmen, aber das soll jz nicht mein Ziel sein ^^

    bb



  • int container[256] = {0};
    	string textdatei = "Ich bin eine in einen String eingelesene Textdatei. Moep moep!";
    	for (int i = 0; i<textdatei.size(); i++ )
    		container[ (int)textdatei[i] ]++;
    	for (int i = 0; i < sizeof(container)/sizeof(int); i++ )
    		if ( container[i] )
    			cout << (unsigned char)i << ": " << container[i] << endl;
    

    SCNR 🙂



  • count0r schrieb:

    int container[256] = {0};
    	string textdatei = "Ich bin eine in einen String eingelesene Textdatei. Moep moep!";
    	for (int i = 0; i<textdatei.size(); i++ )
    		container[ (int)textdatei[i] ]++;
    	for (int i = 0; i < sizeof(container)/sizeof(int); i++ )
    		if ( container[i] )
    			cout << (unsigned char)i << ": " << container[i] << endl;
    

    SCNR 🙂

    Oh no bitte nicht. So ein Code wie von count0r verursacht Programmierer-Krebs.



  • So, anscheinend wurde schon alles wichtige von meinen Vorrednern erwähnt.



  • Ok, soweit läuft es, was mich noch ein wenig stört sind 2 Dinge. Zum einen die Ausgabe (Prozent), da muss ich wohl noch was fixen damit es mir auch nur mit 2 Nachkommastellen angezeigt wird.

    Die andere Sache ist die, dass manche Zeichen ohne Probleme mit eingelesen werden, wenn diese in meiner Textdatei stehen, er bei anderen aber eine unschöne Fehlermeldung ausspuckt.

    ..."Expression: (unsigned)(c+1) <=256

    Zeichen die z.B. nicht gehen wären u.a diese hier: ° = )( / &"...

    andere hingegen wie ,.-#* nimmt er an.

    int main(int argc, char *argv[])
    	{
    		FILE *datei;
    		char str[50];
    		char characters; 	
    		int numclosedfiles = _fcloseall();
    		int h;
    		int alph[27];
    		char textlength;	
    
    		cout << "++++++++++++ Willkommen ++++++++++++";
    		cout << "\n";
    		cout << "\n";
    		cout << "Bitte geben Sie den Namen der Datei ein, die Sie jetzt gerne oeffnen wollen\n";
    		cout << "\n";
    		cin >> str;	
    		cout << "\n";
    		cout << "Sie haben vor folgende Datei zu oeffnen: " << str;
    		cout << "\n";
    
    	// Datei lesen, falls nicht möglich Versuch gescheitert 
    	// Ausgabe wird erzeugt, dass die Datei nicht geöffnet werden konnte 
    
    		fopen_s(&datei, str, "r");
    		if(datei) 
    		{ 
    			for(h =0; h < 27; ++h)
    			{
    				alph[h] = 0;
    			}
    
    			textlength =0;
    
    			map<char, unsigned int> countersec;
    			locale locale;
    			ifstream input(str);
    			char cc;
    			while(input.get(cc))
    			{
    				++textlength;
    				if(isupper(cc)){
    					++alph[cc-'A'];
    				}
    				else if (islower(cc)){
    					++alph[cc-'a'];
    				}
    			}
    
    			characters = textlength - alph[26];
    
    			printf("\nLaenge des Textes: %i \n", textlength);
    			printf("\nAnzahl der Buchstaben: %i \n", characters);
    			cout << "\n";	
    			cout << "Die Datei wurde erfolgreich geoeffnet!\n";
    			cout << "\n";
    
    		typedef std::map<char, unsigned int> Tcounter; 
    		Tcounter counter; 
    
    			ifstream inputse(str);
    				char tmp;
    				while( inputse.get(tmp) ) 
    				{ 
    					char c = tolower(tmp, locale); 
    					++counter[c];
    					cout << tmp << "\n";
    				} 	
    				float sum(0);		
    				for(Tcounter::const_iterator i(counter.begin()), e(counter.end()); i != e; ++i) 
    				{ 
    					sum += i->second; 
    
    				}
    					for(Tcounter::const_iterator i(counter.begin()), e(counter.end()) ; i != e; ++i) 
    					{ 
    
    						float percent = i->second/sum; 
    						cout << "\nDas Zeichen - [" << i->first << "] kommt:" << endl;
    						cout << "" << i->second << "" << " mal vor!" << endl;
    						cout << "Das ergibt folgenden Prozentwert (in Bezug auf alle Zeichen):" << percent*100 << "%" << endl;		
    					} 
    
    		}
    		else 
    		{ 
    			printf("\nDie Datei konnte nicht geoeffnet werden!\n"); 
    		}
    


  • Wenn du mal endlich dein ganzes C gewurschtel rausnehmen würdest, dann würde ich mir den Code auch ansehen.



  • int main(int argc, char *argv[])
    	{
    		FILE *datei;
    		char str[50];	
    		int numclosedfiles = _fcloseall();
    
    		cout << "++++++++++++ Willkommen ++++++++++++";
    		cout << "\n";
    		cout << "\n";
    		cout << "Bitte geben Sie den Namen der Datei ein, die Sie jetzt gerne oeffnen wollen\n";
    		cout << "\n";
    		cin >> str;	
    		cout << "\n";
    		cout << "Sie haben vor folgende Datei zu oeffnen: " << str;
    		cout << "\n";
    
    	// Datei lesen, falls nicht möglich Versuch gescheitert 
    	// Ausgabe wird erzeugt, dass die Datei nicht geöffnet werden konnte 
    		// str = beinhaltet die Eingabe des Users
    		fopen_s(&datei, str, "r");
    		if(datei) 
    		{ 
    
    		typedef std::map<char, unsigned int> Tcounter;
    		locale locale;
    		Tcounter counter; 
    
    			ifstream inputse(str);
    				char tmp;
    				while( inputse.get(tmp) ) 
    				{ 
    					char c = tolower(tmp, locale); 
    					++counter[c];
    					cout << tmp << "\n";
    				} 	
    				float sum(0);		
    				for(Tcounter::const_iterator i(counter.begin()), e(counter.end()); i != e; ++i) 
    				{ 
    					sum += i->second; 
    
    				}
    					for(Tcounter::const_iterator i(counter.begin()), e(counter.end()) ; i != e; ++i) 
    					{ 
    
    						float percent = i->second/sum; 
    						cout << "\nDas Zeichen - [" << i->first << "] kommt:" << endl;
    						cout << "" << i->second << "" << " mal vor!" << endl;
    						cout << "Das ergibt folgenden Prozentwert (in Bezug auf alle Zeichen):" << percent*100 << "%" << endl;		
    					} 
    
    		}
    		else 
    		{ 
    			printf("\nDie Datei konnte nicht geoeffnet werden!\n"); 
    		}
    

    So hoffe das ist jetzt besser. Was die Prozentwerte angeht, da stimmt die Darstellung manchmal und manchmal jetzt nicht, das schwankt zwischen 1 bis 4 Nachkommastellen.

    Was die Zeichen angeht so scheint es kein Problem mehr zu geben.


Anmelden zum Antworten