getline Problem
-
Das Konzept der Schleife habe ich gegoogelt.
Dein Kommentar zur Reihenfolge ist mir unverständlich, zum einen sehe ich keinen Unterschied in der Reihenfolge, zum anderen leuchtet mir nicht ein, warum man nicht folgenden Reihenfolge nimmt.
Überprüfen file Ende
Lesen
Zum String hinzufügenBei deiner Reihenfolge ist der Leseversuch unnötig, wenn das Ende erreicht ist.
Und im Code wird diese Reihenfolge ja nicht eingehalten, sondern in der For Schleife prüfst du ja auch immer zuerst, ob das Ende da ist.
Den einzigen Vorteil deines Codes sehe ich darin, dass man sich paar Zeilen spart.
Jetzt rate mal, was passiert, wenn das getline wegen Dateiendes fehlschlägt.
getline kann doch nicht fehlschlagen, weil das bei mir vorher überprüft wird. Außerdem läuft das Programm doch?
Ich hab vorher schon in der Referenz gesucht, aber jetzt erst gefunden, da es die Funktion zweimal gibt.
www.cplusplus.com/reference/istream/istream/getline/
http://www.cplusplus.com/reference/string/getline/#include <fstream> #include <istream> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> #include <iomanip> using namespace std; int main (int argc, char** argv) { // Argumenteübergabe Fehlermeldung if (argc != 4) { printf ("argument error"); return 0; } string pathToMemory = argv[1]; string pathToAccess = argv[2]; int const cacheTyp = atoi(argv[3]); // Ende // Argumente ersetzen //cout << pathToMemory << " changed to usual\n"; pathToMemory = "Cache.dat"; //cout << pathToAccess << " changed to usual\n"; pathToAccess = "Cache_access.txt"; //Ende //Ausgabe ifstream file; string fileName = "Cache_access.txt"; file.open(fileName.c_str()); // oeffen im Text-Modus if(file) { string text; // Haupttext for (string buffer; getline(file, buffer);) { text += buffer + " an Adresse "; text += buffer + "\n"; // Zeilen zusammensetzen } cout << text; file.close(); } else { cout << "Datei Fehler!"; } //Trennausgabe cout << "===================" << '\n' ; //Ende //Ausgabe2 //Ende return 0; }Ist das der von dir vorgeschlagene Code? Bei mir ist da die Ausgabe gleich.
-
Der Stream kann nicht hellsehen. Der eof-Status wird erst gesetzt, nachdem versucht wird, über das Ende zu lesen. Ist dir nun klar, warum die Reihenfolge einen Unterschied macht?
Ist das der von dir vorgeschlagene Code? Bei mir ist da die Ausgabe gleich.
Zeig mal bitte Inhalt der Datei, die genaue Ausgabe (ich kann gar nicht nachvollziehen, wie die Ausgabe im ersten Programm jemals zustande kommen soll) und prüfe nochmal, ob das wirklich der Code ist, den du derzeit verwendest. Zeig uns nicht Code, der so ähnlich aussieht, wie deiner! Siehe dritter Link in meiner Signatur.
-
#include <fstream> #include <istream> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> #include <iomanip> using namespace std; int main (int argc, char** argv) { if (argc != 4) { printf ("argument error"); return 0; } string pathToMemory = argv[1]; string pathToAccess = argv[2]; int const cacheTyp = atoi(argv[3]); pathToMemory = "Cache.dat"; pathToAccess = "Cache_access.txt"; ifstream file; string fileName = "Cache_access.txt"; file.open(fileName.c_str()); if(file) { string text; for (string buffer; getline(file, buffer);) { text += buffer + " an Adresse "; text += buffer + "\n"; } cout << text; file.close(); } else { cout << "Datei Fehler!"; } string i = "0D5"; i = "0x" + i; cout << i << endl; int const j = atoi(i.c_str()); cout << "dezimal:" << dec << j << endl; cout << "===================" << '\n' ; return 0; }Das ist mein tatsächlicher Code, ich habe da am Ende was weggelassen, was mein nächstes Problem ist. Und zwar geht es da um die Frage, warum
string i = "0D5"; i = "0x" + i; cout << i << endl; int const j = atoi(i.c_str()); cout << "dezimal:" << dec << j << endl;hier die Ausgabe 0 ist, während hier
string i = "0x0D5"; cout << i << endl; cout << "dezimal:" << dec << i << endl;das richtig rauskommt.
Das hier ist der Inhalt meiner Input Datei
216 217 156 157 0D6 0D7 296 297 196 197 216 217 156 157 0D6 0D7 154 155 0D4 0D5Ausgabe
g++ p4.cpp -o p4 ./p4 1 2 3 an Adresse 216 an Adresse 217 an Adresse 156 an Adresse 157 an Adresse 0D6 an Adresse 0D7 an Adresse 296 an Adresse 297 an Adresse 196 an Adresse 197 an Adresse 216 an Adresse 217 an Adresse 156 an Adresse 157 an Adresse 0D6 an Adresse 0D7 an Adresse 154 an Adresse 155 an Adresse 0D4 0D5 an Adresse 0D5 0x0D5 dezimal:0 ===================
-
RTFM für atoi.
Das atoi kann mit dem x (von dem "0x") nichts mehr anfangen und beendet das parsen.
Du solltest strtol nehmen. Das erkennt am Prefix das Zahlensystem wenn base == 0 ist, oder nimmt eine feste Basis, dann brauchst du die "0x"-Krücke nicht.
-
Ich kann absolut gar nichts von dem was du schreibst nachvollziehen. Bei mir gibt dieses Programm absolut korrekt das aus, was man erwarten würde:
216 an Adresse 216 217 an Adresse 217 156 an Adresse 156 ...Und auch bei deiner zweiten Frage liefert atoi bei mir 0, wie es sein sollte (atoi darf nur Dezimalsystem verstehen!) und das zweite gibt einfach den vorher gebildeten String aus. Da läuft etwas ganz furchtbar falsch, wenn da etwas anderes herauskommt!
Spekulation: Welche Version des GCC benutzt du? Mach malg++ -vDirkB schrieb:
RTFM für atoi.
Das atoi kann mit dem x (von dem "0x") nichts mehr anfangen und beendet das parsen.
Du solltest strtol nehmen. Das erkennt am Prefix das Zahlensystem wenn base == 0 ist, oder nimmt eine feste Basis, dann brauchst du die "0x"-Krücke nicht.Da wir hier C++ machen, sollte er sich wohl eher mal einen Stringstream ansehen.
-
Danke für deinen Beitrag DirkB.
Habe meinen Code jetzt so:
#include <fstream> #include <istream> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> using namespace std; int main (int argc, char** argv) { if (argc != 4) { printf ("argument error"); return 0; } string pathToMemory = argv[1]; string pathToAccess = argv[2]; int const cacheTyp = atoi(argv[3]); pathToMemory = "Cache.dat"; pathToAccess = "Cache_access.txt"; ifstream file; string fileName = "Cache_access.txt"; file.open(fileName.c_str()); if(file) { string text; for (string buffer; getline(file, buffer);) { const char * c = buffer.c_str(); char * pEnd; long int i; i = strtol (c,&pEnd,16); //printf ("%ld ", i); text += i; text += buffer + " an Adresse "; text += buffer + "\n"; } cout << text; file.close(); } else { cout << "Datei Fehler!"; } cout << "===================" << '\n' ; return 0; }Meine Ausgabe ist:
g++ p4.cpp -o p4 ./p4 1 2 3 an Adresse 216 an Adresse 217 an Adresse 156 an Adresse 157 an Adresse 0D6 an Adresse 0D7 an Adresse 296 an Adresse 297 an Adresse 196 an Adresse 197 an Adresse 216 an Adresse 217 an Adresse 156 an Adresse 157 an Adresse 0D6 an Adresse 0D7 an Adresse 154 an Adresse 155 an Adresse 0D4 Õ0D5 an Adresse 0D5 ===================Du hast mit Recht gehabt SeppJ, ich habe bei meinem schnellen Post hier string mit int vertauscht, habe das hier gemeint. Aber die Sache hat sich ja jetzt erledigt.
int i = 0x0D5; cout << i << endl; cout << "dezimal:" << dec << i << endl;g++ -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.5 (Debian 4.4.5-8)Das ist zwar nicht die aktuellste (4.7.2 http://gcc.gnu.org/), sollte aber dennoch keine Probleme machen?
-
Vermutlich liegt es daran, dass ich wie wild die untschiedlichsten Dinge in string text reinwerfe, da bin ich wahrscheinlich zu verwöhnt aus Java, wo automatisch konvertiert wird.
-
Dieser Code kann unmöglich mit der gezeigten Datei die gezeigte Ausgabe erzeugen. Dein Compiler ist auch aktuell (genug), aber daran hätte es sowieso nicht liegen dürfen. Bist du wirklich absolut sicher, dass dies der Code ist den du übersetzt und dass du auch wirklich das neu übersetzte Programm benutzt?
const char * c = buffer.c_str(); char * pEnd; long int i; i = strtol (c,&pEnd,16); //printf ("%ld ", i); text += i;Jetzt wird's langsam merkwürdig. Was meinst du, was dieser Code macht? Oder mal anders gefragt: Was soll dein Programm am Ende eigentlich genau machen?
M6KVNE schrieb:
Vermutlich liegt es daran, dass ich wie wild die untschiedlichsten Dinge in string text reinwerfe, da bin ich wahrscheinlich zu verwöhnt aus Java, wo automatisch konvertiert wird.
Das ist Unkenntnis. Das Stichwort Stringstream wurde schon genannt.
-
Ich starte WinSCP und öffne p4.cpp und es erscheint mein Code.
Dann öffne ich Putty und gebeg++ p4.cpp -o p4 ./p4 1 2 3ein. Und dann kommt die Ausgabe. Ich weiß nicht, was da falsch sein könnte. Allerdings hatte ich schon öfter mit dem Server Probleme.
const char * c = buffer.c_str(); char * pEnd; long int i; i = strtol (c,&pEnd,16); //printf ("%ld ", i); text += i;Der Abschnitt soll die zeilenweise eingelesenen hex Zahlen einer Datei in dec umwandeln und dann wieder zeilenweise im Format "dec Text hex" ausgeben.
Am Ende benutze ich dann die dec Zahl, um ein Zeichen an einer von der Zahl bestimmten Position auszulesen und dann stattdessen dort am Anfang ausgeben.
Dann noch ein bisschen Code (der Hauptteil
) und ist es ein Cache.Kannst du mal die volle Ausgabe für folgenden Code posten?
#include <fstream> #include <istream> #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std; int main (int argc, char** argv) { if (argc != 4) { printf ("argument error"); return 0; } string pathToMemory = argv[1]; string pathToAccess = argv[2]; int const cacheTyp = atoi(argv[3]); pathToMemory = "Cache.dat"; pathToAccess = "Cache_access.txt"; ifstream file; string fileName = "Cache_access.txt"; file.open(fileName.c_str()); if(file) { string text; for (string buffer; getline(file, buffer);) { const char * c = buffer.c_str(); char * pEnd; long int i = strtol (c,&pEnd,16); text += i; text += " an Adresse " + buffer + "\n"; } cout << text; file.close(); } else { cout << "Datei Fehler!"; } cout << "===================" << '\n' ; return 0; }
-
Nun, dieser Code ist ja nochmal ganz anders als alles was du vorher gezeigt hast. Die Ausgabe hierzu ist schwer im Forum zu posten, da
Der Abschnitt soll die zeilenweise eingelesenen hex Zahlen einer Datei in dec umwandeln und dann wieder zeilenweise im Format "dec Text hex" ausgeben.
absolut nicht das ist, was der Code macht. Die Ausgabe ist:
an Adresse 216 an Adresse 217 V an Adresse 156 W an Adresse 157 \ufffd an Adresse 0D6 \ufffd an Adresse 0D7 \ufffd an Adresse 296 \ufffd an Adresse 297 \ufffd an Adresse 196 \ufffd an Adresse 197 an Adresse 216 an Adresse 217 V an Adresse 156 W an Adresse 157 \ufffd an Adresse 0D6 \ufffd an Adresse 0D7 T an Adresse 154 U an Adresse 155 \ufffd an Adresse 0D4 \ufffd an Adresse 0D5 ===================Naja, man kann es nicht wirklich erkennen :p . Bei jeder Zeile ist eben irgendein Sonderzeichen am Anfang, welches nicht wirklich forenkompatibel ist. Ich kann mir auch vorstellen, dass dein Putty diese Zeichen gar nicht anzeigt.
Zu deinem eigentlichen Anliegen:
Der Abschnitt soll die zeilenweise eingelesenen hex Zahlen einer Datei in dec umwandeln und dann wieder zeilenweise im Format "dec Text hex" ausgeben.
Wenn du Zahlen möchtest, dann lies Zahlen (folgender Code benötigt noch ein
#include <sstream>):stringstream text; for (int number; file >> hex >> number;) { text << dec << number << " an Adresse " << hex << number << "\n"; } cout << text.str();Habe ich richtig verstanden, dass du es so möchtest?
Am Ende benutze ich dann die dec Zahl, um ein Zeichen an einer von der Zahl bestimmten Position auszulesen und dann stattdessen dort am Anfang ausgeben.
Dann noch ein bisschen Code (der Hauptteil
) und ist es ein Cache.
-
Wo wir gerade dabei sind, wenn Du schon printf benutzen willst, dann binde auch die cstdio statt die stdio.h ein. Mit der stdio.h mischt Du strenggenommen C und
C++.
-
redrew99 schrieb:
Wo wir gerade dabei sind, wenn Du schon printf benutzen willst, dann binde auch die cstdio statt die stdio.h ein. Mit der stdio.h mischt Du strenggenommen C und
C++.Besser: Nutze kein printf, erst recht nicht zur Ausgabe eines statischen Stringliterals. Selbst in C würde man dafür puts benutzen, weil die printf-Formatierung totaler Overkill wäre, den man hier gar nicht nutzt.
-
@SeppJ
Dankeschön für deine Hilfe, hat mir sehr geholfen. Auch wenn ich mich jetzt immer noch frage, warum wir beide untschiedliche Ausgaben hatten.Wen es interessiert, hier mein momentaner Code:
#include <fstream> #include <istream> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <sstream> using namespace std; int main (int argc, char** argv) { if (argc != 4) { printf ("argument error"); return 0; } string pathToMemory = argv[1]; string pathToAccess = argv[2]; int const cacheTyp = atoi(argv[3]); pathToMemory = "Cache.dat"; pathToAccess = "Cache_access.txt"; char c, str[256]; ifstream is; is.open ("Cache.dat"); // open file ifstream file; string fileName = "Cache_access.txt"; file.open(fileName.c_str()); if(file) { stringstream text; for (int number; file >> hex >> number;) { is.seekg (number); c = is.get(); text << c << " an Adresse " << hex << number << "\n"; } cout << text.str(); file.close(); } else { cout << "Datei Fehler!"; } is.close(); cout << "===================" << '\n' ; is.open ("Cache.dat"); // open file fileName = "Cache_access.txt"; file.open(fileName.c_str()); if(file) { stringstream text; for (int number; file >> hex >> number;) { is.seekg (number); c = is.get(); if (true) { text << c << " an Adresse " << hex << number << " Hit\n"; } else { text << c << " an Adresse " << hex << number << "Miss\n"; } } cout << text.str(); file.close(); } else { cout << "Datei Fehler!"; } is.close(); return 0; }Ich muss jetzt "nur" noch die if Abfrage so verändern, dass drei verschiedenen Cachetypen verwendet werden können.
Ausgabe ist jetzt:
./p4 1 2 3 C an Adresse 216 a an Adresse 217 c an Adresse 156 h an Adresse 157 e an Adresse d6 an Adresse d7 h an Adresse 296 i an Adresse 297 t an Adresse 196 an Adresse 197 C an Adresse 216 a an Adresse 217 c an Adresse 156 h an Adresse 157 e an Adresse d6 an Adresse d7 m an Adresse 154 i an Adresse 155 s an Adresse d4 s an Adresse d5 =================== C an Adresse 216 Hit a an Adresse 217 Hit c an Adresse 156 Hit h an Adresse 157 Hit e an Adresse d6 Hit an Adresse d7 Hit h an Adresse 296 Hit i an Adresse 297 Hit t an Adresse 196 Hit an Adresse 197 Hit C an Adresse 216 Hit a an Adresse 217 Hit c an Adresse 156 Hit h an Adresse 157 Hit e an Adresse d6 Hit an Adresse d7 Hit m an Adresse 154 Hit i an Adresse 155 Hit s an Adresse d4 Hit s an Adresse d5 Hit
-
M6KVNE schrieb:
@SeppJ
Dankeschön für deine Hilfe, hat mir sehr geholfen. Auch wenn ich mich jetzt immer noch frage, warum wir beide untschiedliche Ausgaben hatten.Weil dein Code den du hier gezeigt hast ein völlig anderer war:
text += buffer + " an Adresse "; text += buffer + "\n"; // Zeilen zusammensetzen