"?" aus Datei einlesen
-
uerderli schrieb:
also ist doch mit == alles perfekt oder nicht?
Aber nicht bei Zeigern. Da müsstest du diese zuerst dereferenzieren, und nicht mal das klappt - wenn du folgendes machst:
*"Hallo Welt!"ist das Ergebnis 'H'. String-Literale sind nähmlich eigentlich char-Pointer mit Null-Terminatoren.
"Hal" : 0x65464ea 73 //Oder so ähnlich; ASCII-, bzw. ANSI-Werte 0x65464eb 97 0x65464ec 109 0x65464ed 0
-
so hier mal mein Code
#include "stdafx.h" #include <iostream> #include <fstream> #include <string> #define num 9658 #define att 27 using namespace std; int _tmain(int argc, _TCHAR* argv[]) { ifstream datei("auf.txt"); if(!datei) { cerr << "Fehler beim Öffnen"; cin.get(); return 2; } //int* tap; int (*tab)[att] = new int[num][att]; char zeile[70]; char separator[] = ","; char* token; int z = 0, s = 0; datei.getline(zeile, 70); while( datei.getline(zeile, 70)) { s = 0; token = strtok(zeile, separator); /* erstes Token ermitteln */ while( token != NULL ) { //if(token != "no" || token != "yes" || token != "?") if(strcmp(token, "no") != 0 || strcmp(token, "yes") != 0 || strcmp(token, "?") != 0) { tab[z][s] = atoi(token); cout << tab[z][s] << " | "; } else { if(token == "no") tab[z][s] = 0; else if(token == "yes") tab[z][s] = 1; else if(token == "?") tab[z][s] = -42; } token = strtok(NULL, separator); /* weitere Token ermitteln */ ++s; } //cout << endl << z << " geschaft" << endl; //cin.sync(); //cin.get(); ++z; } cout << "Dateneinfelsen abgeschossen" << endl; //double* tab2; double (*tab2)[num] = new double[num][num]; //Distanzmatrix double diff; double sum; for(int i = 0; i < num -1; ++i) { for(int j = i+1; j < num; ++j) { sum = 0; for(int k = 0; k < att - 1; ++k) //cancerler nicht { if(tab[i][k] == -42 || tab[j][k] == -42) diff = 0; else diff = tab[i][k] - tab[j][k]; sum += diff * diff; } tab2[i][j] = sqrt(sum); //cout << endl << i << " " << j << " " << tab2[i][j] << endl; //cin.sync(); //cin.get(); } } cout << "Distanzen berechnet" << endl; double* tab3 = new double[num]; //Mittelwerte der Distanzwerte double sum2 = 0; for(int i = 0; i < num; ++i) { sum = 0; for(int j = 0; j < num; ++j) { if(i == j) sum += 0; else if(i < j) sum += tab2[i][j]; else sum += tab2[j][i]; } tab3[i] = sum / (num -1); sum2 += tab3[i]; //cout << endl << i << " " << tab3[i] << endl; //cin.sync(); //cin.get(); } double median = sum2 / num; cout << "Mittelwerte gebildet" << endl; //cout << median; int a = 0; ofstream outFile("auf2.txt", ios::app); if(!outFile) { cerr << "Fehler beim Öffenen zum Schreiben" << endl; cin.get(); return 2; } for(int i = 0; i < num; ++i) { if(abs(tab3[i] - median) > 8) { ++a; cout << i << endl; } else { for(int j = 0; j < att; ++j) { //if(tab[i][j] < -100) //cout << i << " " << j << endl; if(tab[i][j] == -42) outFile << "?"; else if(j == (att - 1) && tab[i][j] == 0) outFile << "no"; else if(j == (att - 1) && tab[i][j] == 1) outFile << "yes"; else outFile << tab[i][j]; outFile << ","; } outFile << endl; } } cout << endl << a; //265 cin.sync(); cin.get(); return 0; }Warum werden die ? als 0 interpretiert?
Ist es wegen der Vergleiche mit c-strings oder kann generell ein ? nicht eingelesen werden, weil es ein Sonderzeichen ist
-
Dankeschön, das lesen wir natürlich alles sofort.
-
gibt es die Funktion strtok auch für C++-Strings?
-
uerderli schrieb:
gibt es die Funktion strtok auch für C++-Strings?
boost::algorithm::split oder ähnliches...
-
Hacker schrieb:
Dankeschön, das lesen wir natürlich alles sofort.
wirklich!? 
-
Swordfish schrieb:
Hacker schrieb:
Dankeschön, das lesen wir natürlich alles sofort.
wirklich!? 
Nein!

-
danke für eure Hilfe mit den String-Vergleichen.
Aber nochmal zu dem ?.
Trotz korrekter Vergleiche, die das ? immernoch als 0 gelesen.Weißt ihr warum?
-
Hacker schrieb:
Swordfish schrieb:
Hacker schrieb:
Dankeschön, das lesen wir natürlich alles sofort.
wirklich!? 
Nein!

Aha. Das heißt also, ich sollte mein Codebeispiel, in dem das Problem auftritt, so kurz wie möglich halten, damit ich nicht unnötig mehr Zeit der evtl. hilfsbereiten Leser stehle, als nötig?

uerderli schrieb:
Trotz korrekter Vergleiche, die das ? immernoch als 0 gelesen.
Weißt ihr warum?
Nein, wir weissen es nicht.
-
uerderli schrieb:
danke für eure Hilfe mit den String-Vergleichen.
Aber nochmal zu dem ?.
Trotz korrekter Vergleiche, die das ? immernoch als 0 gelesen.Weißt ihr warum?
oh Gott, tschuldigung für meine Rechtschreibung

-
Swordfish schrieb:
Hacker schrieb:
Swordfish schrieb:
Hacker schrieb:
Dankeschön, das lesen wir natürlich alles sofort.
wirklich!? 
Nein!

Aha. Das heißt also, ich sollte mein Codebeispiel, in dem das Problem auftritt, so kurz wie möglich halten, damit ich nicht unnötig mehr Zeit der evtl. hilfsbereiten Leser stehle, als nötig?

Ja.

-
uerderli schrieb:
Mit
token = strtok(zeile, separator);
trenne ich dabei die Werte.Das ist keine gute Idee. Lese doch lieber gleich die Zahlen aus der Datei ein und überlese die Kommas dazwischen. Falls Du Beispiele suchst, suche hier im Forum nach 'csv istream' oder in Google nach 'csv Datei lesen istream'.
Das Einlesen des '?' statt einer Zahl, kann man mit einem sogenannten Manipulator lösen.
Hier eine Code-Skizze:#include <fstream> #include <iostream> #include <string> #include <vector> template< char C > std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } // -- Manipulator, zum Einlesen von Zahlen und einem '?' // wird ein '?' erkannt, so erhält die Zahl den Wert '-42.' struct query { explicit query( double& nr ) : m_number( nr ) {} friend std::istream& operator>>( std::istream& in, query q ) { typedef std::istream::traits_type Traits; if( in >> std::ws && !in.eof() ) { if( Traits::to_char_type( in.peek() ) == '?' ) { in.ignore(1); // '?' überlesen q.m_number = -42.; } else in >> q.m_number; } return in; } private: double& m_number; }; int main() { using namespace std; ifstream datei("datei.txt"); if(!datei) { cerr << "Fehler beim Öffnen"; cin.get(); return 2; } for( int zeile = 1; datei; ++zeile ) { cout << zeile << ".Zeile: "; double zahl; for( int i=0; i<26 && datei >> query( zahl ) >> Char<','>; ++i ) { cout << zahl << "|"; } string yes_no; if( datei >> yes_no ) cout << yes_no; cout << endl; } cin.get(); return 0; }Gruß
Werner
-
@Werner
vielen Dank!so funktioniert es perfekt!
-
Blöde Frage, aber wieso funktioniert das?
for( int i=0; i<26 && datei >> query( zahl ) >> Char<','>; ++i )
Char ist doch eine Funktion, welcher >>-Operator passt da?
-
if(strcmp(token, "no") != 0 || strcmp(token, "yes") != 0 || strcmp(token, "?") != 0)Diese Bedingung kann niemals "false" werden. Jeder mögliche String ist entweder ungleich "no" ODER (||) ungleich "yes" ODER (||) ungleich "?".
Was du suchst ist UND (&&).
-
Ethon schrieb:
Blöde Frage, aber wieso funktioniert das?
for( int i=0; i<26 && datei >> query( zahl ) >> Char<','>; ++i )
Char ist doch eine Funktion, welcher >>-Operator passt da?
Dieser:
namespace std { template <class charT, class traits = char_traits<charT> > class basic_istream : virtual public basic_ios<charT,traits> { public: // Kapitel 27.7.2.2.3 Formatted input: [istream::extractors] basic_istream<charT,traits>& operator>>( basic_istream<charT,traits>& (*pf)(basic_istream<charT,traits>&) ); // 1 Effects: None. This extractor does not behave as a formatted input function (as described in 27.7.2.2.1.) // 2 Returns: pf(*this). // ... } }Funktioniert genau so wie z.B. std::ws.
Gruß
Werner