[c++] Problem bei übergabe
-
Hallo Leute,
ich habe folgendes Problem: Ich habe lese in der main eine Datei zeilenweise aus.
Aus den extrahierten Variablen(string und int) möchte ich mir in der Funktion "Createfilename" einen Dateinamen zusammensetzen.
Leider werden mir die String-werte(prozessname und zifferncode) zwar in die Funktion übergeben aber nicht an die Variable dateinamevar angehängt.
Ich hatte selbiges schon in char-Feldern umgesetzt, was wunderbar funktionierte bis gestern. Dann hab ich es auf String umgemünzt, funkioniert leider auch nicht.Hier der Code:
// sonstige Headerdateien #include <stdio.h> #include <iostream> #include<fstream> #include<iomanip> #include<cstring> #include<math.h> #include<sstream> #include<string> #include <vector> #include <limits> #include <time.h> #ifdef __unix__ //Header für Auslesen der Dateizeit, Unterscheidet Unix und Windows Dateisystem #include <sys/stat.h> #include <sys/types.h> #else #include <sys\stat.h> #endif #define cout STD_COUT //da iostream hier nicht eingefuegt wurde. #define endl STD_ENDL //an anderer Stelle wird das zu std::cout geaendert //Funktionsprototypen void createfilename (std::string& dateinamevar, std::string prozessname, std::string zifferncode, int gatyp, int genometyp, int testfkttyp); //char* ist Zeigervariable, int main(){ // \0 = leerer String char vardat[30]="Variableninput.dat"; //enthält Variablengrenzen //Ergebnisdatei cout << "\n\nEinlesen der Parameter\n\n\n"; cout << "*************************\n"; //Einlesen der Variablen aus Datei vardat std::string dummy, val[6]; // dummy liest String bis : ein, val[] ist stringarray für die Werte, müssen aber noch gecastet werden std::string prozess; //Name des Prozesses std::string zifferncode; //Zifferncodierung oder Datum int gatyp; //zur Wahl des GA-Typs int genometyp; //zur Wahl des Genome-Typs int testfkttyp; //zur Wahk der Testfkt int anzdurchlaeufe; //Anzahl der Durchläufe std::ifstream in(vardat); // neuen Lese-Stream aus Datei vardat erzeugen if( !in.is_open() ) //Fehlerprüfung ob Datei geöffnet werden kann { std::cerr << "Fehler beim Oeffnen der Datei " << vardat << "\n"; return 1; } //1. Zeile auslesen std::getline(in, dummy, ':'); // Einlesen bis : in.ignore(); // Leerzeichen ignorieren std::getline(in, val[0]); // Einlesen bis Zeilenende prozess = val[0]; //2.Zeile auslesen std::getline(in, dummy, ':'); in.ignore(); std::getline(in, val[1]); zifferncode = val[1]; //3.Zeile auslesen std::getline(in, dummy, ':'); in.ignore(); std::getline(in, val[2]); std::istringstream invar(val[2]); invar >> gatyp; //4.Zeile auslesen std::getline(in, dummy, ':'); in.ignore(); std::getline(in, val[3]); invar.clear(); invar.str(val[3]); invar >> genometyp; //5.Zeile auslesen std::getline(in, dummy, ':'); in.ignore(); std::getline(in, val[4]); invar.clear(); invar.str(val[4]); invar >> testfkttyp; //6. Zeile auslesen std::getline(in, dummy, ':'); in.ignore(); std::getline(in, val[5]); invar.clear(); invar.str(val[5]); invar >> anzdurchlaeufe; //Prüfung Ausgabe der eingelesenen Werte auf Screen cout << "prozess: " << prozess << "\n"; cout << "zifferncode: " << zifferncode << "\n"; cout << "gatyp: " << gatyp << "\n"; cout << "genometyp: " << genometyp << "\n"; cout << "testfkttyp: " << testfkttyp << "\n"; cout << "anzdurchlaeufe: " << anzdurchlaeufe << "\n"; std::string dateierg; // Namen der Dateien aus Zeichenkette zusammenbauen createfilename(dateierg, prozess, zifferncode, gatyp, genometyp, testfkttyp); //generiert ersten Teil des Dateinamens dateierg += "_Erg.dat"; //generiert Endung cout << "\n" << dateierg << "\n"; } void createfilename (std::string& dateinamevar, std::string prozessname, std::string zifferncode, int gatyp, int genometyp, int testfkttyp){ //fügt dateinamevar-string die übergebenen strings aus Variableninput an cout << prozessname; dateinamevar += prozessname; dateinamevar+= zifferncode; switch(gatyp){ case 1: dateinamevar += "Simp"; break; case 2: dateinamevar += "Stea"; break; case 3: dateinamevar += "Inc"; break; } switch(genometyp){ case 1: dateinamevar += "B2D"; break; case 2: dateinamevar += "Real"; break; } switch(testfkttyp){ case 1: dateinamevar += "TF1"; break; case 2: dateinamevar += "TF2"; break; case 3: dateinamevar += "ZF"; break; } }Ich hoffe ihr könnt mir helfen. Ich verzweifel da schon 1,5 Tage dran.
Viele Grüße
Guddy
-
Werd mal genauer! Was funktioniert denn nicht? Strings zusammensetzen ist eigentlich kein Problem:
void concatStrings(std::string& s1,std::string s2) { s1+=s2; } std::string s1="Test"; std::string s2="XXX"; concatString(s1,s2);Klappt wunderbar...
BTW: Nimm [cpp ]-Tags statt [code ], ist besser lesbar.
-
Also die Eingabe kannst du da besser mit einer Funktion, oder Schlaufe löschen. Copy/Paste weisst auf eine mögliche Verbesserung des Codes hin.
Zum Problem. Geh da mal mit dem Debugger duch, dann findest du die Stell, wo es deiner Meinung nach nicht das macht, was du denkst. Wenn du den Fehler dann nicht selber lösen kannst, kannst du du ein wenig genauer posten, was dir nicht klar ist, warum etwas anders geht.
-
Deine Funktion zur Namenserzeugung funktioniert ganz ausgezeichnet. Bist du sicher, dass beim Einlesen deiner Werte alles richtig ist? Das kommt mir sehr umständlich vor, wie du das machst, aber ich kenne jetzt ja auch nicht dein Dateiformat.
-
Ich hab das Problem soweit eingegrenzt:
// sonstige Headerdateien #include <stdio.h> #include <iostream> #include<fstream> #include<iomanip> #include<cstring> #include<math.h> #include<sstream> #include<string> #include <vector> #include <limits> #include <time.h> #ifdef __unix__ //Header für Auslesen der Dateizeit, Unterscheidet Unix und Windows Dateisystem #include <sys/stat.h> #include <sys/types.h> #else #include <sys\stat.h> #endif using namespace std; //Funktionsprototypen int main(){ // \0 = leerer String char vardat[30]="Variableninput.dat"; //enthält Variablengrenzen //Ergebnisdatei cout << "\n\nEinlesen der Parameter\n\n\n"; cout << "*************************\n"; //Einlesen der Variablen aus Datei vardat string dummy; string prozess; //Name des Prozesses ifstream in(vardat); // neuen Lese-Stream aus Datei vardat erzeugen if( !in.is_open() ) //Fehlerprüfung ob Datei geöffnet werden kann { cerr << "Fehler beim Oeffnen der Datei " << vardat << "\n"; return 1; } //1. Zeile auslesen getline(in, dummy, ':'); // Einlesen bis : in.ignore(); // Leerzeichen ignorieren getline(in, prozess); // Einlesen bis Zeilenende std::string dateierg=""; cout << "prozessname: " <<prozess << "free\n"; }Wenn ich in der Inputdatei nach dem ": " folgendes stehen habe: "Bla"
bekomme ich folgende Ausgabe: in der letzten Code-Zeile:freeessname: BlaAnscheinend wird die Variable Bla bis Zeilenende eingelesen. Obwohl ich die Datei in Linux editiert habe und der Zeilenumbruch direkt nach "Bla" nach Enter gesetzt wurde. getline nimmt ja automatisch "\n" als delimit-Wert, wenn nichts weiter angegeben wurde.
-
setze ich einen anderen delimiter, wie z.B. "/" im Code und der Inputdatei funktionierts einwandfrei. Aber eigentlich möchte ich das nicht. Wo wird denn der Zeilenumbruch gesetzt, wirklich nach der "Entereingabe"?
-
Enter ist Zeilenumbruch ja.
Aber ich verstehe nicht ganz, wo dein Problem ist.
cout << "prozessname: " <<prozess << "free\n";Ergibt dir mit prozessname = "bla" das da ?
freeessname: Bla
-
hmm... ist jetzt einw enig geraten, aber das sieht mir nach folgendem aus:
- in der Datei steht nach dem Bla ein Zeilenumbruch, und zwar windowstypisch ein CR gefolgt von einem LF.
Das getline(in, prozess) liest bis zum LF, was dazu fürht dass in prozess sowas wie "Bla \r" steht - also der CR mit im String drin ist. Da du den CR also mit ausgibst wird nach dem Bla der Cursor an den Zeilenanfang gesetzt und das free überschreibt die ersten 4 Buchstaben der Zeile...
-
Danke Pumuckl,
das wußte ich nicht und so funktionierts.gibt es eine Möglichkeit sicherzustellen, dass das Dateiformat Unix oder Windows ist? Ich müsste sicherstellen das mein Programm noch läuft. auch wenn jemand änderungen in der Datei in Windows als auch Linux macht.
Viele Grüße
Guddy
-
guddy schrieb:
Ich hab das Problem soweit eingegrenzt:
Dürfte ich dich um ein paar Dinge bitten, wenn du willst das dir viele helfen?
1. Minimiere das Programm auf den Problemfall, dies umfasst auch:
a) Includiere nur das, was für den Fall nötig ist
b) Vermeide das mischen mehrerer Sprachen (Hier C und C++), sofern du dich damit schon auskennst.2. Formatiere den Code so, das er auch für andere lesbar ist
a) Einrückungen auf Scopeebene (jeder Scope sollte sauber erkennbar sein)
b) Vermeide unnötig viele Leerzeilen, einzelne können zum Verständnis beitragen, viele führen zu einer optisch zu starken Trennung.
c) Wähle bezeichner so, das auch andere ihren Sinn erkennen können (vardat sagt z.B. garnichts aus).cu André
-
Es gibt im linux ein command dos2unix oder unix2dos. mit
shell(dos2unix "Dateiname") stelle ich sicher, dass das Format passt. Problem gelöst.Danke für eure Hilfe.
Viele Grüße
Torsten