txt datei einlesen und bearbeiten in c++



  • 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.



  • bmth schrieb:

    ...

    grausam
    du hast dir nicht mal mühe gemacht, den geposteten code zu verstehen -.-

    #include <string> //string
    #include <iostream> //cin, cout, endl
    #include <fstream> //ifstream
    #include <cstdlib> //EXIT_FAILURE
    #include <map> //map
    #include <locale> //locale
    
    using namespace std; //auch, wenn ich eigtl kein freund davon bin ^^
    
    typedef map<char, unsigned int> Tchar_counter;
    
    int main()
    {
    	cout << "Dateiname:" << endl;
    	string filename;
    	std::getline(cin, filename);
    
    	ifstream input(filename.c_str());
    	if(!input.is_open())
    		return EXIT_FAILURE;
    
    	Tchar_counter char_counter;
    
    	char character;
    	locale our_locale;
    	while( input.get(character) )
    	{
    		if( isalpha(character, our_locale) )
    			character = tolower(character, our_locale);
    		++char_counter[character];
    	}
    
    	Tchar_counter::mapped_type sum = Tchar_counter::mapped_type();
    	for(Tchar_counter::const_iterator i(char_counter.begin()), e(char_counter.end()); i != e; ++i) 
    	{ 
    		sum += i->second;
    	}
    
    	cout.precision(2);
    	for(Tchar_counter::const_iterator i(char_counter.begin()), e(char_counter.end()) ; i != e; ++i) 
    	{ 
    		float percent = i->second/float(sum); 
    		cout << i->first << ": " << percent*100 << " %" << endl;
    	}
    
    	//schließen verhindern -> enter drücken um zu schließen
    	cin.clear();
    	cin.ignore( cin.rdbuf()->in_avail() );
    	cin.get();
    }
    

    nicht optimal - aber allemal besser, als das, was du hattest 😛

    bb



  • Warum denn immernoch printf( )!? 😕
    Btw: In welcher Steinzeit hat man mit fopen_s( ) gearbeitet?



  • Also so alt/schlecht scheint fopen_s nach meinen Eindrücken nicht zu sein. Da ich (gerade noch mal ein wenig nachgeschaut) dutzende Beispiele damit gefunden habe, die zudem noch gar nicht so alt sind ^^.

    So weiter gehts 😃

    Das Programm läuft jetzt wunderprächtig 🙂 Vielen Dank noch mal für die Hilfe!

    Eine weitere Sache wäre jetzt aber noch die Eingabe des Users. Ich hatte mir überlegt eine kleine Kontrolle einzubauen ob es sich z.B. um eine ASCII oder ANSI Datei handelt.

    Dafür brauche ich ja unter anderem CharToOem bzw. OemToChar. Dafür habe ich auch schon Beispiele gefunden, jedoch waren die leider nicht so das wahre fand ich. Eins wäre z.B. dieses hier:

    char charToOem(char character)
    { 
      char conv[2] = {character, '\0'};
      // Vorsicht: in = out ist nur bei der ANSI-Version erlaubt
      CharToOemA(conv, conv); 
      return conv[0];
    }
    
    bool getCharFromConsole(int x, int y, char& character) {
      CHAR_INFO buffer;
      COORD bufferSize = {1, 1};
      COORD bufferCoord = {0, 0};
      SMALL_RECT region = {x, y, x, y};  
      if(ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), &buffer, bufferSize, bufferCoord, &region ) == 0)
        return false;
      else {
        character = buffer.Char.AsciiChar;
        return true;
      }
    }
    

    Und dazu gehörig entsprechend:

    char character;
    if(getCharFromConsole(1, 0, character)) {
      printf("\n\nGelesen: %c\n\n", charToOem(character));
    }
    else {
      // Fehler beim Lesen des Zeichens ...
      // Passiert z.B. bei ungültigen Koordinaten
    }
    

    Jetzt Frage ich mich ob man das Ganze nicht komfortabler und "schöner" lösen kann. Hätte jemand von euch da eine alternative Lösung (Idee)? 🙂


Anmelden zum Antworten