merkwürdiges verhalten von getline?



  • hallo, ich hab da ein kleines problemchen

    irgendwie spinnt da was.

    int servHandle::config(const std::string& file)
    {
    	bool pathState=false;
    	bool portState=false;
    	bool enableLog=false;
    	std::string logfile="null";
    	std::ifstream stream(file.c_str()); 
    	if(!stream){
    		std::cout<<"\nError: no licserv.conf file found\n";
    		return 1;
    	}
    	else{
    		std::string tmp;
    		while(!stream.eof()){	
    			getline(stream, tmp);
                               //hier is das merkwürdige////////
                               std::cout<<"tmp:"<<tmp<<" foo\n";
                               ///////////////////////////////// 
    			if((tmp.find("licPath:", 0)!=std::string::npos)&&(tmp.at(0)!='#')){
    				int index=tmp.find("licPath:", 0);
    				licFile=tmp.substr(index+8);
    				pathState=true;
    			}
    ...
    

    bei der ausgabe std::cout<<"tmp:"<<tmp<<" foo\n"; wird "foo" am anfang der zeile gesetzt, und wenn ich dann licFile=tmp.substr(index+8); mache und das mit std::cout<<licFile<<"foo\n"; ausgebe wird der anfang von licFile mit "foo" überschrieben.

    ausgabe--std::cout<<"tmp:"<<tmp<<" foo\n";
    foolicPath:blabla
    ausgabe--std::cout<<licFile<<"foo\n"; (licFile=tmp.substr(index+8);)
    fooPath:blabla

    woran liegt das?

    folgende headers benutze ich:

    #include "servHandle.h"
    #include <time.h>
    #include <iostream>
    #include <sys/ioctl.h>
    #include <sstream>
    #include <fstream>
    #include <net/if.h> 
    #include <netinet/ether.h> 
    #include <string>
    #include <map>
    #include <pthread.h>
    #include "tomcrypt.h"
    

    gruß part



  • Das Verhalten sieht ganz danach aus, als hättest du eine Textdatei in Binärmodus (oder eine Windows-Datei unter Linux) eingelesen - getline() hat zwar das \n verschluckt, aber nicht das \r aus dem Windows-Zeilenende \r\n (normalerweise sollte letzteres schon vom Stream-Buffer vernichtet werden).



  • ja das prog läuft unter linux und die einzulesende datei habe ich unter windows erstellt.

    genau das war der fehler 🙂
    hab jetz mal getline(stream, tmp; '\r') genommen das funzt.
    oder löst man das problem anders?

    vielen dank auf jedenfall für die antwort 🙂



  • Hmm ich würde das einlesen evtl. so gestalten, und nicht abhängig von Variablennamen:

    void servHandle::read_config(std::string const & file_name, std::map<std::string, std::string>& config_data)
    {
    	config_data.clear();	
    	std::ifstream file_stream(file_name.c_str());
    	if (!file_stream) throw std::invalid_argument("could not open file");
    
    	std::string line_tmp;
    	while (std::getline(file_stream, line_tmp))
    	{
    		std::clog << "line tmp: \"" << line_tmp << "\"" << std::endl;
    		if (line_tmp.at(0) == '#') continue;
    
    		const std::size_t colon_pos(line_tmp.find(':'));
    		if (colon_pos == std::string::npos)	continue; /* oder exception, da ungültiger Syntax! */
    
    		config_data[line_tmp.substr(0, colon_pos)] = line_tmp.substr(colon_pos + 1);
    	}
    }
    

    ...

    aja zu deiner Headerauflistung: <ctime> anstelle von <time.h> 🙂



  • part schrieb:

    hab jetz mal getline(stream, tmp; '\r') genommen das funzt.
    oder löst man das problem anders?

    Wenn es dich nicht stört, daß du das NewLine dann am Anfang der nächsten Zeile zurückbleibt (und daß du keine Linx-Dateien damit verarbeiten kannst), dürfte die Lösung ausreichen 😉 Ansonsten müsstest du das überflüssige \r eventuell manuell entfernen:

    getline(stream,tmp);
    if(tmp[tmp.size()-1]=='\r') tmp.erase(tmp.size()-1));
    


  • (D)evil hab die header geändert 😉
    ich les zwar keine linux dateien ein, aber werde trotzdem deine Variante nehmen CStoll die is wohl etwas sauberer.

    vielen dank für eure antworten



  • part schrieb:

    ich les zwar keine linux dateien ein, aber werde trotzdem deine Variante nehmen CStoll die is wohl etwas sauberer.

    Randfrage: Was machen Windows Dateien überhaupt auf einem Linux System?



  • es geht um einen floating license server der auch auf linux laufen soll.
    die lizenz dateien werden aber unter windows erstellt, da die hier auf arbeit nur windows nutzen.



  • part schrieb:

    es geht um einen floating license server der auch auf linux laufen soll.

    "auch"?

    die lizenz dateien werden aber unter windows erstellt, da die hier auf arbeit nur windows nutzen.

    Wie erstellst du denn die Lizenzdateien? Wenn du das mit C/C++ machst, gibt es eine einfache Lösung - öffne die Dateien (auf beiden Seiten) als ios::binary, dann werden die Zeilenumbrüche nicht mehr für's System umgerechnet, sondern bleiben als nackte '\n' stehen.



  • jo der läuft nun unter windows und linux, jetzt kommt noch unix und das apfel-OS

    mach das mit c++ ja, werd das dann mit dem ios::binary machen, vielen dank.
    wusste bis eben noch net das windows sowas macht.

    gruß part



  • part schrieb:

    jo der läuft nun unter windows und linux, jetzt kommt noch unix und das apfel-OS

    Ja, da ist es definitiv besser, sich nicht auf den Textmodus zu verlassen - der Apple macht afaik wieder etwas ganz anderes und codiert das Zeilenende als "\n\r".


Anmelden zum Antworten