Klasse string als Parameter in Funktion
-
Übergib nicht 'string*' sondern 'string const&'.
Den Iterator-Typ bekommst Du per 'string::iterator'. Also:
for (string::iterator i = line.begin(); i != line.end(); ++i) // ...
-
CSVInterface::FindCellDouble(string const& str_line,int n) { // Finde eine bestimmte Zelle einer Zeile str_line::iterator line_i; line_i = str_line.begin(); cout << line_i << endl; // test return 0; // Später Wert für Rückgabe }Ich habe alles rausgenommen und fang nochmal von vorne an.
Oben stehende Funktion funktioniert immer noch nicht.
Fehler: str_line keine Klasse oder Namespace
Der Zugriff auf Methoden funktioniert (str_line.begin())Ich möchte aus einem Datensatz (csv Datei) Werte auslesen. Diese stehen an unterschiedlichen Stellen und haben unterschiedliche Typen. Dazu möchte ich eine Funktion nutzen, in der ich als Parameter die Zeile, welche ich vorher durch getline erhalten habe, und die Spalte angebe. Als Rückgabewert kommt dann der Wert, der innerhalb der begrenzenden ; steht. Soviel zum dem was ich haben möchte.
-
etsmart schrieb:
Oben stehende Funktion funktioniert immer noch nicht.
Fehler: str_line keine Klasse oder NamespaceSowohl CStoll als auch Konrad Rudolph haben doch geschrieben, wie du an den Iterator kommst

-
etsmart schrieb:
... str_line::iterator line_i; ...CStoll schrieb:
...Der richtige Typ nennt sich 'string::iterator'....
etsmart schrieb:
...cout << line_i << endl; ...Ein Iterator ist nur "eine Art Verweis" - denn kannst/willst Du nicht direkt ausgeben, sondern das, worauf er verweist:
...cout << *line_i << endl; ...etsmart schrieb:
...
Ich möchte aus einem Datensatz (csv Datei) Werte auslesen. Diese stehen an unterschiedlichen Stellen und haben unterschiedliche Typen. Dazu möchte ich eine Funktion nutzen, in der ich als Parameter die Zeile, welche ich vorher durch getline erhalten habe, und die Spalte angebe. Als Rückgabewert kommt dann der Wert, der innerhalb der begrenzenden ; steht. Soviel zum dem was ich haben möchte.Dann tu das doch

Ab Position n das nächste ';' suchen (geht auch mit "std::find()") und das dazwischen mittels ato-Funktionen oder boost::lexical_cast oder .... umwandeln.Gruß,
Simon2.
-
der eine sagt:
const string& wertder andere
string const& wertwieder ein anderer sagt:
const string const& wertalso was nun?
ich persönlich benutze lieber:
const string& wertaber im endeffekt ist das doch furz wie deckel, da es sich nicht um einen zeiger handelt, oder?
-
Mit Zeigern hat das nichts zu tun. Ob das 'const' vor oder hinter dem Typ steht, ist ganz egal. Ich schreibe 'const' immer hinter den Typ, weil man es bei einer Funktion genauso macht. Einen anderen Grund hat's für mich nicht.
'const' sowohl vor als auch hinter den Typ ist natürlich nicht sehr sinnvoll. Ich weiß nichtmal, ob der Compiler das zulässt.
-
Naja:
const user schrieb:
der eine sagt:
const string& wert
string const& wertDas ist Geschmackssache (so, wie "A==B" oder "B==A"). Ich persönlich ziehe Zweiteres vor (weil es bei Pointern IMO einfacher zu lesen ist, "const wirkt auf den Vorgänger").
const user schrieb:
const string const& wert
Das ist einfach falsch ("doppeltes const").
EDIT:
Konrad Rudolph schrieb:
...weil man es bei einer Funktion genauso macht....
Auch ein gutes Argument !!

Gruß,
Simon2.
-
CSVInterface::FindCellDouble(string const& str_line,int n) { // Finde eine bestimmte Zelle einer Zeile string::iterator line_i; for(line_i = str_line.begin();line_i !=str_line.end();line_i++) { // Fehler: const char * kann nicht in char* konvertiert werden cout << *line_i; } cout << endl; return 0; }Ich glaube ich steh im Walde. Oben das funkt. auch nicht.
CSVInterface::FindCellDouble(string const& str_line,int n) {Referenzen nutzt man indem:
typ& name = variable;
oder
typ const& name = variable, wenn der zu übergebende Wert nicht verändert werden kann.string::iterator line_i;string::iterator ist ein Datentyp, der in string steht. line_i ist also eine Variable vom Typ iterator.
for(line_i = str_line.begin();line_i !=str_line.end();line_i++) {begin() liefert einen Wert vom Typ iterator zurück. Also gebe ich diesen Wert an line_i weiter
cout << *line_i;Da line_i ein Verweis ist, erfolgt der Zugriff wie bei einem Zeiger (ein * vorangestellt)
Wo liegt mein Fehler?
-
*grübelt kurz* Welche Anweisung verursacht denn den Fehler?
*nach etwas längerem Nachdenken* Du hast einen 'const string', das heißt, du benötigst dort auch einen 'string::constiterator'.
-
Mein Fehler. Da der String const ist, kann er natürlich nicht manipuliert werden. Wenn Du nur Zeichen ausgeben willst, verwende statt 'iterator' einfach 'const_iterator'. Wenn Du den String bzw. Iterator manipulieren willst, mach das 'const' bei der Parameterübergabe weg.
-
CSVInterface::FindCellDouble(string& str_line,int n) { // Finde eine bestimmte Zelle einer Zeile string s = str_line; //"Testlauf"; string::iterator i; cout << "\nFindCellDouble:\t"; for(i=s.begin();i!=s.end();i++){ if(*i == ',') *i = '.'; cout << *i; } cout << "\t:"<< endl; return 0; }Jetzt hab ichs
-
etsmart schrieb:
CSVInterface::FindCellDouble(string& str_line,int n) { // Finde eine bestimmte Zelle einer Zeile string s = str_line; //"Testlauf"; string::iterator i; cout << "\nFindCellDouble:\t"; for(i=s.begin();i!=s.end();i++){ if(*i == ',') *i = '.'; cout << *i; } cout << "\t:"<< endl; return 0; }Jetzt hab ichs
Hmmm - kann ich nicht finden:
Konrad Rudolph schrieb:
...Wenn Du nur Zeichen ausgeben willst, verwende statt 'iterator' einfach 'const_iterator'.
Wenn Du den String bzw. Iterator manipulieren willst, mach das 'const' bei der Parameterübergabe weg.- Für das einfache Suchen und Daten daraus extrahieren, brauchst Du kein "non-const" str_line.
- WENN Du schon ein "non-const" str_line einsetzt, brauchst Du erst Recht keine Kopie (s) davon....Gruß,
Simon2.
-
Habt natürlich recht...die Funktion hat es auf jeden Fall schon mal.
Das einzige was mir jetzt noch fehlt, ist mir das Ende der Zeile der CSV Datei zurückzugeben. Die letzten Werte werden einfach wiederholt, wenn ich über die Grenze hinaus zugreife.
Mit der Funktion CellValueDouble kann ich über den Dateinamen und Koordinaten einen bestimmten Wert aus einer CSV auslesen und zurückgebenfor(int m=2;m<=14;m++) for(int n=32;n<=34;n++) cout << " " << CellValueDouble(pszFilename,m,n); cout << endl;Zeigt mir die 2. bis 14.Spalte in der 32. bis 34. Zeile an.
Weitere Schritte wären Änderungen in einer bestimmten Zelle zu speichern und halt das Ende der Zeile zu ermitteln, damit nicht immer die letzte Zelle wiederholt wird
double CSVInterface::FindCellDouble(string& s,int n) { // Finde eine bestimmte Zelle einer Zeile -> Double //string s = str_line; //"Testlauf"; string::iterator i; int first = 0; int last = 0; int m = 0; for(i=s.begin();i!=s.end();i++){ // Punkt mit Komma ersetzen für Funktion strtod() if(*i == ',') *i = '.'; } do { last = s.find(';',first); if(last != -1) { IGBTDaten.temp.assign(s,first,last-first); m++; //cout << "\n" << first << " " << last << " " << m << " " << IGBTDaten.temp; first = last+1; } // if if(last == -1) { IGBTDaten.temp.assign(s,first,s.size()-first); m++; //cout << "\n" << first << " " << last << " " << m << " " << IGBTDaten.temp; } // if if(first == -1 && last == -1) return -1; }while( m<n && last != -1 /* && first != last */); //}while(s.size() >= last); //cout << endl; return strtod(IGBTDaten.temp.c_str(),0); } double CSVInterface::CellValueDouble(char* pszFilename,int x,int y) { // Wert aus einer bestimmten Zelle mit Koordinatenangabe ->Double string line; ifstream file; // Erstellt Objekt zum Dateien lesen file.open(pszFilename); // Öffnet diese Datei if(file.is_open()) { while(!file.eof()) { for(int i=0;i<y;i++) { getline(file,line); } // for return FindCellDouble(line,x); } // while } // if if(!(file.is_open())) cout << " File konnte nicht geöffnet werden " << endl; if(file.eof()) cout << " Ende der Datei erreicht " << endl; file.close(); return -1; }