txt datei einlesen und bearbeiten in c++



  • die Zeile

    double abst += Koords::dist(p[k], p[k-1]);
    

    liefert mit sicherheit nicht das gewüncschte, denn du legst jedes mal in der for schleife eine variable 'abst' an und addierst auf diese neu erstellte variable eine distanz.
    Was du jedoch machen möchtest ist, alle distanzen zu addieren. Dazu brauchst du VOR der for-schleife
    double abst = 0;
    und IN der for-schleife
    abst += Korrds::dist(p[k], p[k-1]);

    Falls du dich wundern solltest wieso bei dir der abstand immer falsch ist.



  • So, ich poste mal ganz dreist mein Problem hier rein, da es vom Titel her gut passt.

    Kurze Info was gemacht werden soll:

    User gibt einen Dateinamen ein, Datei soll geladen/geöffnet werden, Buchstaben auf Häufigkeit gezählt und entsprechend ausgegeben werden.

    int main(int argc, char *argv[])
    {
    	FILE *datei;
    	char c;
    	char str[50];
    	errno_t err;
    	//err = &datei;
    	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;
    		ifstream input("");
    
    		while(input.get(str))
    		{
    			c = tolower(str, locale);
    			++counter[str];
    
    		}
    			for_each(counter.begin(), counter.end(), &printCounter);
    

    Derzeit bekomme ich noch die Fehlermeldung:

    error C2664: 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::get(_Elem &)' : cannot convert parameter 1 from 'char [50]' to 'char &'

    Hatte auch schon versucht Lösungen aus dem Forum etc. einzubringen aber bisher leider ohne Erfolg 😕

    Jemand eine Idee?



  • Wenn du uns jetzt auch noch sagst in welcher Zeilöe die Fehlermeldung auftaucht, müssen wir nicht raten 🙂

    im Übrigen würde ich dir davon abraten, C-FILEs mit C++-fstreams zu vermischen. Entweder oder...



  • Mit Zeile 5 provozierst du einen Bufferoverflow...



  • Kóyaánasqatsi schrieb:

    Mit Zeile 5 provozierst du einen Bufferoverflow...

    Nur wenn es mehr als 50 chars geben wird..

    A. ) Benutz kein FILE/fopen/fclose gefrickel

    B. ) Wieso ein char array? std::string ist doch viel besser, und sicherer.

    C. ) Das kann man viel hübscher machen...



  • Oh, sry das hatte ich nicht mit kopiert. Er meckert Zeile 63 an (while(input.get(str)))

    Mh also mir hatten man gesagt ich sollte am besten FILE + fopen und Co. benutzen und entsprechend die notwendigen Return Werte übergeben. Ich bin jetzt verwirrt was hier die bessere Option ist 😃 Die einen sagen machs so, die anderen wieder ne mach das lieber so und so.

    Hättest du denn ein Beispiel wie ich es, deiner Meinung nach anders/besser machen kann ohne da all zu viel umschreiben zu müssen?



  • Kóyaánasqatsi schrieb:

    Mit Zeile 5 provozierst du einen Bufferoverflow...

    Mit einer Arraydefinition kann man einen Overflow provozieren?



  • bmth schrieb:

    Oh, sry das hatte ich nicht mit kopiert. Er meckert Zeile 63 an (while(input.get(str)))

    while(input.get(str, sizeof(str)))



  • Ok, der Fehler ist weg, dafür meckert er dann bei den anderen "str´s".

    fopen_s(&datei, str, "r"); 
    	if(datei) 
    	{ 
    		cout << "Die Datei wurde erfolgreich geoeffnet!\n";
    		cout << "\n";
    		map<char, unsigned int> counter;
    		locale locale;
    		ifstream input(str);
    
    		while(input.get(str, sizeof(str))) 
    		{
    			c = tolower(str, locale);
    			++counter[str];
    
    		}
    			for_each(counter.begin(), counter.end(), &printCounter);
    

    Einmal hier:

    error C2440: '=' : cannot convert from 'char *' to 'char'
    
    =>c = tolower(str, locale);
    

    Und dann:

    error C2679: binary '[' : no operator found which takes a right-hand operand of type 'char [50]' (or there is no acceptable conversion)
    
    => ++counter[str];
    

    Was den ersten Fall angeht, so kann ich meines Wissens nach nicht innerhalb der Klammer was konvertieren da er sonst annimmt dass ich z.B. 3 Argumente übergeben will. Folglich gibt es dann auch einen Error.

    Beim Counter wird er ja genau wie vorher wohl dasselbe Problem haben 😕



  • 1. Fehler.:
    http://www.cplusplus.com/reference/std/locale/tolower/
    ->
    charT tolower (charT c, const locale& loc);
    du hast aber
    char tolower ( char* c, const locale& loc);
    du darfst eben immer nur ein einziges zeichen übergeben - sollte aber eigtl klar sein ^^

    2. Fehler.:
    meinst du dort nicht eher ++counter[c]; ?!

    ich würd die schleife anders schreiben - so entfallen mehrere probleme:

    char tmp;
        while( input.get(tmp) )
        {
            char c = tolower(tmp, locale);
            ++counter[c];
        }
    

    zu get:
    http://www.cplusplus.com/reference/iostream/istream/get/

    bb



  • bmth schrieb:

    Ok, der Fehler ist weg, dafür meckert er dann bei den anderen "str´s".

    {
    			c = tolower(str, locale);
    			++counter[str];
    
    			
    		}
    

    Einmal hier:

    error C2440: '=' : cannot convert from 'char *' to 'char'

    =>c = tolower(str, locale);
    

    Das geht so nicht. Bitte sieh mal nach, wie man tolower benutzt, und was der Unterschied zwischen einem Zeiger auf ein char (in Deinem Fall str) und einem char ist.



  • Stimmt der eine Fehler war das str im Counter, wo c hin musste. Was den Rest angeht, so hatte man mir diese Lösung vorgeschlagen, jedoch war die ja scheinbar nicht 100% korrekt.

    Aber es klappt jetzt mit dem öffnen + auslesen der Datei inklusive zählen der Buchstaben 🙂

    Als nächstes werde ich mich dann mal versuchen die entsprechenden Prozente zu berechnen (Alle Zeichen insgesamt und in Bezug darauf die % Werte (mit 2 Nachkommastellen) für die einzelnen Buchstaben.

    Vielleicht melde ich mich gleich dann noch mal, falls ich wo hängen bleibe. Aber danke noch mal für die fixe Hilfe 🙂



  • Mh ok...also teilweise komme ich noch nicht an die richtigen Werte dran.

    Was ja sicher ist -> in tmp steht dann die Anzahl der Zeichen drin (insgesamt).

    Nur wie mache ich es jetzt am besten dass ich für jeden der Buchstaben meine % rauskriege.



  • erstmal alles zusammenrechnen und dann einfach teilen? Oo

    bb



  • Was ja sicher ist -> in tmp steht dann die Anzahl der Zeichen drin (insgesamt).

    Öhm nö.

    Nur wie mache ich es jetzt am besten dass ich für jeden der Buchstaben meine % rauskriege.

    Öhm Dreisatz ?



  • Ja dass ich dafür nen Dreisatz brauche ist mir bewusst. Aber irgendwas passt noch nicht.

    Ich hab jetzt z.B. in meiner .txt Datei folgendes stehen:

    "ABCDABCABA"

    Sprich 4xA; 3xB etc.

    So, raus bekomme ich gerade:

    A0
    B0
    C0
    D0
    A1
    B1
    C1
    A1
    B1
    A2

    ^^



  • oO

    Zeig mal noch ma Code, pls ^^

    bb



  • fopen_s(&datei, str, "r");
    	if(datei) 
    	{ 
    		cout << "Die Datei wurde erfolgreich geoeffnet!\n";
    		cout << "\n";
    		map<char, unsigned int> counter;
    		locale locale;
    		ifstream input(str);
    
    		while( input.get(tmp) ) 
    		{ 
    			char c = tolower(tmp, locale); 
    			++counter[c];
    			cout << "\n" << tmp;
    
    		}
    			for_each(counter.begin(), counter.end(), &printCounter);
    

    Bitte sehr ^^

    Also wie gesagt, es wird eine Eingabe des Users getätigt. Ist die Eingabe korrekt und die Datei existiert, dann wird zunächst eine Statistik ausgegeben. In dieser wird angezeigt wie oft welcher Buchstabe/Zeichen/Zahl vor kommt.

    Resultierend aus der Häufigkeit des einzelnen Zeichens in Bezug auf die Gesamtzahl aller Zeichen soll dann eine Prozentangabe berechnet und ausgegeben werden (Beispiel: 4, 50(%)).

    Und das klappt gerade bei mir halt noch nicht.

    *Ich hab meine Dreisatz Klamotten mal entfernt, weil das war wohl Murks, darum die Ausgabe wie in meinem vorherigen Post*



  • locale locale; compiliert? Oo

    open_s(&datei, str, "r");
    das wurde aber schon gesagt, dass man die FILE* fkt nich mit streams mischen sollte, oder?!

    std::map<char, unsigned int> counter;
    std::ifstream input("dateiname.txt");
    while( input.get(tmp) ) 
    { 
       char c = tolower(tmp, std::locale()); 
       ++counter[c];
    }
    std::for_each(counter.begin(), counter.end(), &printCounter);
    

    bb



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


Anmelden zum Antworten