Kleiner Fehler im Programm zum Filtern von Eintraegen[C++][geloest]

  • Themenstarter Themenstarter sw33tlull4by
  • Beginndatum Beginndatum
S

sw33tlull4by

Guest
Hi!
Sprache ist C++.
Das nachfolgende Programm ist zugegebener massen sehr unstruckturiert sollte allerdings auch nicht erweitert werden sondern nur einmal zum Einsatz kommen.
Problem dabei ist nun, getline((std::fstream,std::string);
keine neuen Zweilen erwischt, sondern immer die gleichen nimmt.
Das Curiose dabei ist das es sich genau an die Anzahl der Zeilen haelt,
aber die ausgegebenen Zeilen nicht mit der Aktuellen uebereinstimmen.
Code:
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<algorithm>

/*
 *Dieses Programm wird sehr einfach und unschoen programmiert werden
 *da ich es nicht erweitern und nur einmal brauchen werde
 */

using std::cout;
using std::cin;
using std::endl;

int main(int argc,char**argv)
{
	std::string hitlist;
	std::string filterfile;

	std::string hitline,filterline,backupfilterline,hitkey,filterkey,tmp;
	std::stringstream tmp2(std::stringstream::in|std::stringstream::out);

	int startposition,foundposition;
	bool found;
	startposition = foundposition = -1;

	cout<<"Bitte Datei mit Hitliste eingeben:"<<endl;
	cin>>hitlist;

	cout<<endl<<"Bitte zu filternde Datei eingeben:"<<endl;
	cin>>filterfile;

	std::fstream hit(hitlist.c_str(),std::fstream::in);
	std::fstream filter(filterfile.c_str(),std::fstream::in);
	filterfile +="result.csv";
	std::fstream result(filterfile.c_str(),std::fstream::out);

	while(!filter.eof())
	{
		found = false;
		filterline = filterkey = "";
		std::getline(filter,filterline);
		backupfilterline = filterline + "\n";
		foundposition = startposition = -1;
		while(true)
		{
			startposition = foundposition +1;
			foundposition = filterline.find(";",startposition);
			if(foundposition ==std::string::npos)
				break;
			else
				filterline.replace(foundposition,1," ");
		}

		tmp2.flush();
		tmp2<<filterline;
		tmp2>>tmp;
		filterkey += tmp;
		tmp2>>tmp;
		filterkey += tmp;
		tmp2>>tmp;
		tmp2>>tmp;
		tmp2>>tmp;
		filterkey += tmp;


		while(!hit.eof())
		{
			hitline = hitkey = "";
			std::getline(hit,hitline);
			startposition = foundposition = -1;

			cout<<"eingelesen:"<<hitline<<endl;
			while(true)
			{
				startposition = foundposition +1;
				foundposition = hitline.find(";",startposition);
				if(foundposition == std::string::npos)
					break;
				else
					hitline.replace(foundposition,1," ");
			}
			cout<<"bearbeitet:"<<hitline<<endl;

			tmp2.flush();
			tmp2<<hitline;
			for(int i = 1;i<=3;i++)
			{//in dieser Schleife ist der Fehler aber ich weiss nicht wo
				tmp2>>tmp;
				hitkey = hitkey+tmp;
				cout<<tmp<<endl;
			}

			cout<<hitkey<<"<=>"<<filterkey<<endl;
			cin.get();

			if(hitkey.compare(filterkey) == 0)
			{
				cout<<"ich komme hier nicht rein\n";
				found = true;
				break;
			}
		}
		hit.clear();
		hit.seekg(std::fstream::beg);

		if(!found)
			result<<backupfilterline;
	}

	hit.close();
	filter.close();
	result.close();

	return 0;
}

Zur illustration koennt ihr das Programm ja mal kompilieren und die angehaengten *.csv datein angeben.
Erst Mappe2.csv dann Mappe1.csv
Es sollten nur die Zeilen welche nicht in beiden Datein vorkommen ausgegeben werden.
mfg

sw33t
 
In awk hab ich noch nicht geschafft; Aber hier mal ein Shellscript:
Code:
comp1=($(cat test1.txt | cut -d\; -f 3,4))
comp2=($(cat test2.txt | cut -d\; -f 3,4))

for str in ${comp1[*]}; do
   i=0
   while (( $i < ${#comp2[*]} )); do
      if [[ $str = ${comp2[i]} ]]; then
         cat test1.txt | grep $str
      fi
      (( i += 1 ))
   done
done
test1
Code:
HALLO
Hallo
1
2
3
test2
Code:
Superman!!
HALLO
1
TESTTER!!
3
Ausgabe
Code:
HALLO
1
3
 
Sehr schön, aber das ist keine Programmieraufgabe :D.
Das was mein Programm leisten soll ist auch so einfach wie es nur geht, ABER
ich finde den Fehler nicht, ich mache in meiner Syntax irgendwas falsch, und ich komme nicht dahinter.
Hab schon mal tmp2.str(der String) anstelle von tmp2<<der String;
probiert, habe tmp2 auch mal geflusht(zur Errinerung tmp2 ist vom Typ StringStream,
und ich habe auch schon mal str1 == str2 anstelle von str1.compare(str2)==0 geschrieben,und solche Scherze.
Aber es haut einfach nicht hin und das macht mich ungehalten und leider ist es so das wenn ich in so einer Situation den Fehler nicht sehe, ich ihn 2 oder 3 Tage später auch nicht sehe, weswegen ich die Frage hier gestellt habe.
mfg

sw33t

btw:
Dein Shellskript entspricht nicht ganz dem was ich versuche in C++ zu machen, denn es soll nur das ausgegeben werde was in Datei2 aber nicht in Datei 1 vorkommt, sollte in Datei1 was stehen was in Datei2 nicht vorkommt wird das ignoriert.
Die Ausgabe muesste also
Superman!!
TESTER!!
lauten
 
Zum einen hat deine Datei am ende jeweils ein \r\n was Probleme macht.

Dann ersetzt du die ";" durch " " hast aber in den eigentlichen Daten auch Leerzeichen. Eine Bestimmung der passenden Spalten geht dann nichtmehr.
Es wäre vielleicht möglich einfach nicht benötigte Spalten zu löschen und dann den Vergleich durchzuführen, ohne die Spalten zusammenzufügen.

Auch kann eine Datei einen anderen Fehler als ein EOF haben. Prüfen auf good() ist vielleicht leichter.

Ein flush() löscht nicht den Inhalt des Streams. Entweder du erstellst ihn jedesmal lokal neu oder du setzt hinter das flush noch "tmp2.ignore(numeric_limits<streamsize>::max())" und "tmp2.clear();".
Das flush ist glaub ich auch überflüssig.

Bei mir kommt dann als result:
Code:
asdaskdjh;khk;jh
kuhjkjh;khj;kjhkjh
asdasd;asdasd;adsasdasd
 
Vielen dank fuer deine Antwort, wie immer praezise und Problemloesend.
mfg

sw33t
 
Zurück
Oben