neues problem mit stdout
-
so nachdem ich nun erfolgreich meine daten aus der shell in einer txt speicher hab ich ne neue idee

ich wills direkt in die sturkt umleiten, da es sehr mühseelig ist, auf diverse leerstellen in der txt zu reagieren, weil nicht alle spalten zwangsweise belegt sind. nun möchte ich, das ich die daten, die an stdout geleitet werden, direkt in meine struct zeile für zeile, oder eher wert für wert übergebe, so müsste man ja auch direkt auf einen leeren inhalt einfacher reagieren können.
wäre sehr dankbar wenn mir einer folgen kann und mir da hilfreich wäre ^^
danke und cYa CAD
-
ich denke ich kann dir helfen, habe aber keine Ahnung, was du willst

Gib mal n Beispiel.MfG
GPC
-
also ich hab ne datei mit ner liste der laufwerksdaten alá :
Volume Bst Bezeichnung DS Typ Gr”áe Status Info ---------- --- ----------- ----- ---------- ------- --------- -------- Volume 0 W DVD 0 B Volume 1 Z CD 0 B Volume 2 O DVD 0 B Volume 3 P DVD 0 B Volume 4 Q DVD 0 B Volume 5 R DVD 0 B Volume 6 G Programme NTFS Partition 20 GB OKnun habe ich ne struct, die die daten erhalten soll. wenn ich aber die daten aus der datei einlese und das an die struct übergebe is das mühseelig, da ich jedes mal testen muss, ob der inhalt leer ist, was danach kommt und wohin der aktuelle zeichen demnach gehört. ich wills so machen das der zeile für zeile die ausgabe von stdout an die struct umlenkt, weis aber net wie ich das struct array eins weiter schalte und auch net wie ich stringweise die stdout auslese .
is nun klarer was ich meine ? ^^ ich glaub ich seh irgendwie langsam selbst net mehr richtig durch

danke für dein interesse GPC
-
Ach stimmt, du bist ja der, der die komischen Partitionen macht

na ja, das geht eigentlich ganz einfach. Du liest diese Datei von der Festplatte:
#include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; int main() { ifstream ifs("test.txt"); if (!ifs) return 1; string s(""); vector<string> vec; while (ifs.good()) { getline(ifs, s); //ok, jetzt haben wir eine Zeile im string s vec.push_back(s); //..und rein in den vector } ifs.close(); //jetzt haben wir die Datei zeilenweise in vec return 0; };So, jetzt kannst sie einfach an das struct übergeben. Wenn du das nicht willst, wäre noch die Möglichkeit, den >> Operator deines structs zu überladen:
struct Foo { int i; }; istream& operator>>(istream &is, const Foo &f) { return is>>f.i; };Dann kannst du gemütlich schreiben:
Foo f; cout<<"Zahl eingeben: "; cin>>f;MfG
GPC
-
wow gpc bis du nen schneller

ich der mit den komischen partitionen ...

ich danke dir für den source und werd das morgen umbaun. zur zeit lese ich die liste aus ner txt ein und lasse sie säubern. das funzt auch sehr gut jetzt ^^ is nur eben 200 zeilen code für das weng arbeit

deine funktion sieht da extrem geschmeidiger aus ^^
danke und schlaf gut ich meld mich morgen nachmittag mit dem neuesten stand

cYa CAD
-
hmm ich komm wie schon vermutet net klar

ich habe keinen vector, sondern eine struct vom typ LaufwerksDaten
struct LaufwerksDaten { TCHAR szBuchstabe[10]; TCHAR szDateiSystem[10]; TCHAR szBezeichnung[20]; TCHAR szGroessenAngabe[5]; TCHAR szDatenTyp[10]; TCHAR szStatus[10]; TCHAR szInfo[10]; int iGroesse; int iIndex; };und habe versucht den string s komplett an die struct zu übergeben, die struct soll sich dann selber string für string die daten zuordnen, leider klappt das net, habsmit nem cast versucht willer net ^^ ich bin auf dem gebiet noch net so bewandert.

dann ist noch eine sache:
ich würde gern die ausgabe von stdout statt in die datei direkt an meine struct übergeben, nachdem ich den string "---------" gefunden habe, was der letzte uninteressante string in der liste ist, alle nachfolgenden daten sollen an die struct gehen. ist sowas net möglich gleich? da müsste ich mir nämlich nicht gedanken machen wo ich auf nem unformatierten system die file.txt ablege ^^danke für deine mühe wie gesagt

cYa CAD
-
MasterCAD schrieb:
struct LaufwerksDaten { TCHAR szBuchstabe[10]; TCHAR szDateiSystem[10]; TCHAR szBezeichnung[20]; TCHAR szGroessenAngabe[5]; TCHAR szDatenTyp[10]; TCHAR szStatus[10]; TCHAR szInfo[10]; int iGroesse; int iIndex; };sorry, aber das ist mist. Muss es unbedingt TCHAR sein? Wieso nicht std::string?
struct LaufwerksDaten { string buchstabe; //usw. int groesse; int index; };Wäre viel einfacher, außerdem musst du dich auch nicht um die Größe kümmern. Btw. Ungarische Notation ist übel in C++.
und habe versucht den string s komplett an die struct zu übergeben, die struct soll sich dann selber string für string die daten zuordnen, leider klappt das net, habsmit nem cast versucht willer net ^^ ich bin auf dem gebiet noch net so bewandert.

Wir haben mehrere Möglichkeiten:
entweder wir geben dem struct Laufwerksdaten im Konstruktor nen string (eine Zeile der txt Datei) mit und der Konstruktor wertet den aus und weist den Elementen die Werte zu.
Oder wir splitten die Zeile vorher auf und übergeben das dann häppchenweise (nicht so toll).
Oder wir überladen den >> operator, wie ich das gesagt hatte. Vermutlich die beste Lösung.
struct LaufwerksDaten { string buchstabe; string dateiSystem; string groessenAngabe; string datenTyp; string status; string info; int groesse; int index; }; istream& operator>>(istream &is, const LaufwerksDaten &ld) { is>>ld.buchstabe; is>>ld.dateiSystem; //usw.... is>>ld.index; return is; }; //in main: ifstream ifs("test.txt"); if (!ifs) return 1; vector<LaufwerksDaten> vec; LaufwerksDaten l; while (ifs.good()) { ifs>>l; vec.push_back(l); }Ja, sieht ganz nett aus, finde ich^^
ich würde gern die ausgabe von stdout statt in die datei direkt an meine struct übergeben, nachdem ich den string "---------" gefunden habe, was der letzte uninteressante string in der liste ist, alle nachfolgenden daten sollen an die struct gehen. ist sowas net möglich gleich?
Sehe ich das richtig, anstatt etwas in eine Datei zu schreiben, sollen die Werte in ein struct geschrieben werden?
Nicht dass wir uns falsch verstehen, stdout ist die Standardausgabe (eigentlich ist stdout ja C, in C++ nennt sich's cout), stdin ist die Standardeingabe, also meistens die Konsole.MfG
GPC
-
jo sieht wirklich sehr super aus gpc

ich löse es zur zeit so, damit du dir nen bild machen kannst was ich hier so verzapft hab ^^
#include <stdio.h> #include <iostream> #include <fstream> #include <windows.h> //------------------------------------------------------------------------------ using namespace std; enum Pfad { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z}; //------------------------------------------------------------------------------ struct LaufwerksDaten { TCHAR szBuchstabe[10]; TCHAR szDateiSystem[10]; TCHAR szBezeichnung[20]; TCHAR szGroessenAngabe[5]; TCHAR szDatenTyp[10]; TCHAR szStatus[10]; TCHAR szInfo[10]; int iGroesse; int iIndex; }; // Globale //------------------------------------------------------------------------------ fstream FS; int iIndex = 0; LaufwerksDaten Laufwerk[25]; // Vorwärtsdeklarationen //------------------------------------------------------------------------------ const char* LadeString( int n); const char* CleanVorn( const char* cString); const char* CleanHinten( char* cString); void LadeRohDaten(); void SortiereLaufwerke(); // Main //------------------------------------------------------------------------------ int main(int argc, char *argv[]) { FS.open( "callist.txt", ios::out); FS << "LIST VOLUME" << endl; FS.close(); int i; // Liste erstellen ! freopen( "file.txt", "wt", stdout ); system( "diskpart.exe /s callist.txt"); freopen( "CON", "w", stdout ); LadeRohDaten(); ofstream dat_aus; dat_aus.open( "clean.txt", ios::out); // ausgabe der gefüllten struktur zur kontrolle // ob alle daten richtig formatiert eingelesen wurden for( i = 0; i < iIndex; i++) { dat_aus << Laufwerk[i].iIndex << "*" << "\t*"; dat_aus << Laufwerk[i].szBuchstabe << "*" << "\t*"; dat_aus << Laufwerk[i].szBezeichnung << "*" << "\t*"; dat_aus << Laufwerk[i].szDateiSystem << "*" << "\t*"; dat_aus << Laufwerk[i].szDatenTyp << "*" << "\t*"; dat_aus << Laufwerk[i].iGroesse << "*" << "\t*"; dat_aus << Laufwerk[i].szGroessenAngabe << "*" << "\t*"; dat_aus << Laufwerk[i].szStatus << "*" << "\t*"; dat_aus << Laufwerk[i].szInfo << "*" << endl; } dat_aus.close(); SortiereLaufwerke(); // ausgabe der structur, zur kontrolle ob alle laufwerksbuchstaben // richtig zugeordnet wurden dat_aus.open( "sortiert.txt", ios::out); for( i = 0; i < iIndex; i++) { dat_aus << Laufwerk[i].iIndex << "*" << "\t*"; dat_aus << Laufwerk[i].szBuchstabe << "*" << "\t*"; dat_aus << Laufwerk[i].szBezeichnung << "*" << "\t*"; dat_aus << Laufwerk[i].szDateiSystem << "*" << "\t*"; dat_aus << Laufwerk[i].szDatenTyp << "*" << "\t*"; dat_aus << Laufwerk[i].iGroesse << "*" << "\t*"; dat_aus << Laufwerk[i].szGroessenAngabe << "*" << "\t*"; dat_aus << Laufwerk[i].szStatus << "*" << "\t*"; dat_aus << Laufwerk[i].szInfo << "*" << endl; } dat_aus.close(); system("pause"); return EXIT_SUCCESS; } // liest einen string von der länge n aus der datei, die in main geöffnet wurde //------------------------------------------------------------------------------ const char* LadeString( int n) { char zeichen; char puffer[25]; int i; for( i = 0; i < n; i++) { FS.get( zeichen); puffer[i] = zeichen; } puffer[i] = '\0'; return CleanVorn(puffer); } // schneidet alle leerzeichen vor dem string ab //------------------------------------------------------------------------------ const char* CleanVorn( const char* cString) { int i, k, j; char puffer[25]; for( i = 0; i < strlen( cString); i++) { if( cString[i] != ' ') { break; } } for( k = i, j = 0; k < strlen( cString); k++, j++) { puffer[j] = cString[k]; } puffer[j] = '\0'; return CleanHinten( puffer); } // Schneidet alle leerzeichen nach dem eigentlichen string ab //------------------------------------------------------------------------------ const char* CleanHinten( char* cString) { int i; char puffer[25]; for( i = 0; i < strlen( cString); i++) { if( cString[i] == ' ') { break; } } cString[i] = '\0'; return cString; } //------------------------------------------------------------------------------ void LadeRohDaten() { char puffer[25]; int i; FS.open( "file.txt"); // suchen nach 1. gültigem Volume eintrag while( FS.eof() != true) { FS >> puffer; if( !( strcmp( puffer, "--------"))) { break; } } // Newline zeichen abfangen ! strcpy( puffer, LadeString(1)); do { // 2 Leerzeichen lesen strcpy( puffer, LadeString( 2)); // volume einlesen strcpy( puffer, LadeString(6)); // Zwischenzeichen abfangen ! strcpy( puffer, LadeString(1)); // Index einlesen Laufwerk[iIndex].iIndex = atoi( LadeString(2)); strcpy( puffer, LadeString(4)); // Laufwerksbuchstabe einlesen strcpy( Laufwerk[iIndex].szBuchstabe, LadeString(1)); strcpy( puffer, LadeString(2)); strcpy( Laufwerk[iIndex].szBezeichnung, LadeString(11)); // Dateisystem einlesen ( NTFS oder FAT) strcpy( puffer, LadeString(2)); strcpy( Laufwerk[iIndex].szDateiSystem, LadeString(5)); // Datentyp einlesen ( CD/ DVD/ Partition oder Wechselmed) strcpy( puffer, LadeString(3)); strcpy( Laufwerk[iIndex].szDatenTyp, LadeString(10)); strcpy( puffer, LadeString(2)); // Laufwerksgröße einlesen Laufwerk[iIndex].iGroesse = atoi( LadeString(5)); // Laufwerksgrößenangabe einlesen ( B, MB oder GB) strcpy( Laufwerk[iIndex].szGroessenAngabe, LadeString(2)); strcpy( puffer, LadeString(2)); // Status einlesen ( OK oder nix) strcpy( Laufwerk[iIndex].szStatus, LadeString(9)); strcpy( puffer, LadeString(2)); // Laufwerksinfo einlesen ( System oder nix) strcpy( Laufwerk[iIndex].szInfo, LadeString(8)); strcpy( puffer, LadeString(1)); iIndex++; } while( FS.eof() != true); FS.close(); iIndex--; } //------------------------------------------------------------------------------ void SortiereLaufwerke() { for( int i = 0; i < iIndex; i++) { // Wenn aktuelle bezeichnung "Download", checken, ob es auch D:\ ist if( !( strcmp( Laufwerk[i].szBezeichnung, "Download"))) { // Wenn nicht D:\ if( strcmp( Laufwerk[i].szBuchstabe, "D")) { WechselBuchstaben( i, "D"); } } switch ( puffer) { case ("Download"): { cout << Laufwerk[i].szBuchstabe << endl; break; } } } }manche funktionen, wie die SortiereLaufwerke() existieren zur zeit nur rudimentär, da die noch nicht ausgereift sind

aber du weist nun sicher eher was ich überhaupt tue oder vorhabe gpc. im grunde ist die ganze funktion, die file.txt formatiert einzulesen sicher etwas noobylike, aber ich habe ne menge aus büchern gelernt und stelle nun mehr und mehr fest, das der stoff aus büchern und die waren probleme des lebens 2 verschieden große paar schuhe sind. ich muss eben nach und nach lernen wie man was effektiv löst ^^ und irgendwelche streams umlenken etc tu ich zum ersten mal und tu mich somit auch noch sehr schwer damit
.deine idee, das ganze like operatoroverloading in die sctruct zu laden ist sicher eine idee, das hatte ich so auch schon längst gelöst, das prob ist aber, das er da bei leeren inhalten durcheinander kommmt und einfach das nächste zuweist, also in diesem fall ist beschreibung leer, da weist der einfach beschreibung den inhalt von DateiTyp zu und so kommt das gesamte gefüge durcheinander.
die lösung über LadeRohDaten() wie ich es jetzt gebaut habe sieht sehr vergewaltigt aus, das ist mir auch klar. es ist aber so ziemlich die einzige praktikable lösung die mir einfällt. was mir eben gefallen würde, wäre, wenn
ichfreopen( "file.txt", "wt", stdout ); system( "diskpart.exe /s callist.txt"); freopen( "CON", "w", stdout );das irgendwie statt in file.txt direkt an Laufwerk[i] weiterleiten könnte.
danke und cYa CAD
// Edit
wegen dem TCHAR, nein das ist nicht zwingend, aber ich lese zur zeit den Louis und der redet viel von unicode und zeug und ich wollte das ich mit dem programm später auf der dos ebene keinerlei probleme bekomme, das wird mal die formatier und partitionier funktion der XP install CD ablösen. und ich möchte nicht das es dann an sonen sachen scheitert ^^ berichtige mich gern falls ich da nen denkfehler oder unbegründete zweifel habe.
und ja ich weis das is noch net 100% unicode conform, is aber nen mühsamer anfang stabilen code zu fabrizieren.
-
okay, da bin ich wieder. Ich hab mir deinen Code jetzt mal angeschaut, bin aber noch nicht so schlau drauß geworden. Testen konnte ich ihn auch nicht, da ich Linux verwende. Die von dir angesprochenen Probleme habe ich aber teilweise lösen können. Hier mal "etwas" Code:
#include <iostream> #include <fstream> #include <string> #include <vector> using namespace std; struct LaufwerksDaten { string volume; int index; char buchstabe; string bezeichnung; string dateiSystem; string datenTyp; int groesse; string groessenAngabe; string status; string info; }; ostream& operator<<(ostream &os, const LaufwerksDaten &ld) { return os<<"---------------\n" <<ld.volume<<'\n' <<ld.index<<'\n' <<ld.buchstabe<<'\n' <<ld.bezeichnung<<'\n' <<ld.dateiSystem<<'\n' <<ld.datenTyp<<'\n' <<ld.groesse<<'\n' <<ld.groessenAngabe<<'\n' <<ld.status<<'\n' <<ld.info<<'\n' <<"---------------\n\n"; }; //Funktionen LaufwerksDaten parseString(const string&); //Splittet einen String auf vector<string> readFile(const char *); //Liest eine Datei zeilenweise ein string trim(string); //entfernt fuehrende und folgende Leerstellen int main() { //Datei einlesen, hab deine Tabelle von oben genommen vector<string> v = readFile("test.txt"); vector<LaufwerksDaten> file; //Jetzt parsen und in den vector packen vector<string>::iterator it = v.begin(); for ( ; it != v.end(); ++it) file.push_back(parseString(*it)); //mal probeweise ausgeben vector<LaufwerksDaten>::iterator iter = file.begin(); for ( ; iter != file.end(); ++iter) cout<<*iter; return EXIT_SUCCESS; }; //Liest aus str die Infos raus LaufwerksDaten parseString(const string &str) { string s = str; LaufwerksDaten ld; //Volume ld.volume = trim(s.substr(2,11)); s.erase(s.begin(), s.begin()+9); //Index ld.index = atoi(s.substr(0,1).c_str()); s.erase(s.begin(), s.begin()+6); //Laufwerksbuchstabe ld.buchstabe = s[0]; s.erase(s.begin(), s.begin()+4); //Bezeichnung ld.bezeichnung = trim(s.substr(0,9)); s.erase(s.begin(), s.begin()+13); //Dateisystem ld.dateiSystem = trim(s.substr(0,4)); s.erase(s.begin(), s.begin()+7); //Typ ld.datenTyp = trim(s.substr(0,9)); s.erase(s.begin(), s.begin()+14); //Groesse + Einheit string tmp = s.substr(0,5); int pos = tmp.rfind(' '); if (pos != -1) { ld.groesse = atoi( trim(tmp.substr(0,pos)).c_str() ); ld.groessenAngabe = tmp.substr(pos+1, tmp.size()-1); } else ld.groessenAngabe = tmp; s.erase(s.begin(), s.begin()+7); //Status ld.status = trim(s.substr(0,2)); s.erase(s.begin(), s.begin()+11); //Info ld.info = trim(s); return ld; }; vector<string> readFile(const char *file) { ifstream ifs(file); if (!ifs) abort(); vector<string> vec; string s(""); while (ifs.good()) { getline(ifs, s); vec.push_back(s); } ifs.close(); //Die oberen zwei Zeilen fliegen gleich mal raus, brauchen wir eh nicht vec.erase(vec.begin(), vec.begin()+2); return vec; }; string trim(string s) { while (s[0] == ' ') s.erase(s.begin()); while (s[s.size()-1] == ' ') s.erase(--s.end()); return s; };Die parseString Funktion ist erheblich kürzer, aber immer noch nicht schön, ist jetzt nur ne Brute-Force Lösung. Aber es funktioniert. Wenn du wirklich einen guten Parser willst: in der Artikel-Abteilung gibt's nen Artikel zu Boost::Spirit, ein Parser Framework.
Wegen dem TCHAR, ich hab jetzt std::string genommen, v.a. weil es so suckt, ständig mit strcpy durch die Gegend zu rödeln. Ich weiß nicht, gibt's in den MFC oder so keine String-Klasse, die Unicode unterstüzt?
Wenn du Fragen zu meinem Code hast, immer her damit

EDIT: Wenn man in der parseString das ganze erase Zeug weglässt und nur mit substr arbeitet, kann man den Code noch kürzen und u.U. ein bisschen schneller machen.
MfG
GPC
-
das ja super lieb gpc
danke dir für die viele arbeit.ich arbeite so und so net mit der MFC und will das auch gar net erst einführen, daher weis ich net was es da gibt , oder was da geht. für deine viele arbeit erstma nen mega danke. ich bau die nacht noch an ner andern problematik, wie ich dann die erhaltenen laufwerksbuchstaben übergebe und die programme silent installiere. oder eher halbsilent. ich lasse die tasten von einzelnen programmen betätigen als säße wer davor da sich viele programme silent dämlich oder vollkommen unakzeptabel installieren lassen, bis hin zum einfachen entpacken in ne angegebene dir, was ja net sinn und zweck sein kann.
ich hab mir die arbeit rausgesucht, weil ich net dachte, das einer so schnell ne lösung anbieten kann/will
und selber nur auf die oben gegebene kam und nun ne elegantere suchte.ich bin morgen und übermorgen auch net da, da familienmitglieder ihre geburt feiern ^^ aber dienstag setz ich mich sofort ran und wünsch dir bis dahin und nen wunderschönes osterfest und danke dir nochma tausend ma für deine mühe

ich denk das dann sicher am dienstag auch noch ne menge fragen kommen werden ^^
so long und cYa CAD