¨Lesen eines Textfiles mit Komma-deliminator

UncleBob

Mitglied
Nicht allzulange ists her da haben mir gute Seelen hier geholfen ein File zu schreiben. Jetzt muss ich eines Lesen. Kann mich daran erinnern das vor längerer Zeit mal in .net gemacht zu haben, aber .net kann ich für dieses Projekt nicht brauchen.

Was ich bis jetzt zusammengebastelt habe sieht so aus:

Code:
#include "string.h"
#include "stdio.h"
#include <fstream>
#include <iostream>

using namespace std;

void ConvertHyg(void)
{
	
	string Text1;
	string Nope;
	float Yeah;
	string Oha;

	ifstream mInFile("hygxyz.txt");
	
	while( getline(mInFile, Text1, ',') )		
	{						
	    mInFile >> Nope;		        
	    mInFile >> Nope;                   
	    mInFile >> Nope;
	    mInFile >> Nope;		        
	    mInFile >> Nope;                   
	    mInFile >> Nope;			
		mInFile >> Oha;
		mInFile >> Nope;			
		mInFile >> Yeah;
	    mInFile.get();	
	}

}

Der Grund warum soviel nach "Nope" geschrieben wird ist dass dies daten sind die im File stehen, ich aber nicht benötige (das File ist beinahe 10MB gross, und ich brauche nicht einmal die Hälfte der vorhandenen Daten). Wie auch immer, bis dorthin komme ich vorerst mal nicht. Mein Compiler hat folgendes auszusetzen:

Code:
1>e:\empty spaces\goin 3d\04.movement\es_cluster.cpp(23) : error C3861: "getline": Bezeichner wurde nicht gefunden.
1>e:\empty spaces\goin 3d\04.movement\es_cluster.cpp(25) : error C2679: Binärer Operator '>>': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'std::string' akzeptiert (oder keine geeignete Konvertierung möglich)
1>        c:\programme\microsoft visual studio 8\vc\include\istream(995): kann 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char *)' sein
1>        with
1>        [
1>            _Elem=char,
1>            _Traits=std::char_traits<char>
1>        ]

etc...
Zuerst einmal, offensichtlich wird "getline" nicht als Funktion erkannt, was es eigentlich müsste (habe diese Schreibweise in beinahe allen Beispielen gefunden). Es scheint sehr ähnlich wie das Problem das ich letztesmal gehabt habe. Sollte ich einen anderen Syntax verwenden? oder müsste ich noch etwas inkludieren?
 
Hi.
Nicht allzulange ists her da haben mir gute Seelen hier geholfen ein File zu schreiben. Jetzt muss ich eines Lesen. Kann mich daran erinnern das vor längerer Zeit mal in .net gemacht zu haben, aber .net kann ich für dieses Projekt nicht brauchen.

Was ich bis jetzt zusammengebastelt habe sieht so aus:

Code:
#include "string.h"
#include "stdio.h"
System-Headerdateien werden mit spitzen Klammern und nicht mit Anführungsstrichen eingebunden.

Headerdateien der C Standardbibliothek werden in C++ ohne Endung und mit dem Präfix "c" eingebunden. (\edit: aber das hatten wir doch schon mal ;-] http://www.tutorials.de/forum/c-c/343277-mehrdeutiges-symbol.html#post1776463)
Der Grund warum soviel nach "Nope" geschrieben wird ist dass dies daten sind die im File stehen, ich aber nicht benötige (das File ist beinahe 10MB gross, und ich brauche nicht einmal die Hälfte der vorhandenen Daten).
Evlt. solltest du dir mal std::istream::ignore anschauen. Ich weiß aber nicht warum du dort wortweise vorgehst...
Sollte ich einen anderen Syntax verwenden? oder müsste ich noch etwas inkludieren?
Wenn du mal eine Referenz zu Hand nimmst, siehst du dass getline(std::istream&, std::string&, char) in der string Headerdatei deklariert ist (die du sowieso einbinden mußt da du std::string verwendest).

Gruß
 
Zuletzt bearbeitet:
Code:
Headerdateien der C Standardbibliothek werden in C++ ohne Endung und mit dem Präfix "c" eingebunden. (\edit: aber das hatten wir doch schon mal

In der Tat... wenn ich string includiere anstatt string.h sind die Fehler weg! vielen Dank!

Damit mir das nicht wieder passiert: woran zum Geier erkenne ich denn ob es sich um eine C standardbibliothek handelt die ohne erweiterung inkludiert werden muss oder ob es sich um eine andere handelt? :confused:

Code:
Ich weiß aber nicht warum du dort wortweise vorgehst...

Weil jeder output in eine andere Variable überladen werden soll. Vielleicht kann man das auch besser regeln?
Wie auch immer, die Sache mit der Deliminierung scheint noch nicht so ganz zu klappen... Momentan wird für jedes >> eine ganze Zeile eingelesen, nicht bloss bis zum nächsten Komma. Woran könnte das liegen?
 
Zuletzt bearbeitet:
Hallo Bob,

C-Headerdateien haben eine Endung mit .h z.b. #inlclude <string.h> Möchtest du solch eine Headerdatei in C++-Projekten einbinden dann lässt man das .h weg und schreibt ein kleines c davor z.b. #include <cstring> So wie es deepthroat schon gesagt hat. Benutze eine Referenz ! z.b. wiki oder cpluplus

Für die viele Vorhaben brauchst du keine C-Headerdateien da sollten die Standard C++ header reichen also in deinem Fall #include <string>

Gruß
 
Damit mir das nicht wieder passiert: woran zum Geier erkenne ich denn ob es sich um eine C standardbibliothek handelt die ohne erweiterung inkludiert werden muss oder ob es sich um eine andere handelt? :confused:
Das muss man wissen. Oder man muss halt nachschauen wo die Klassen, Funktionen etc. deklariert sind.
Code:
Ich weiß aber nicht warum du dort wortweise vorgehst...

Weil jeder output in eine andere Variable überladen werden soll. Vielleicht kann man das auch besser regeln?

Wie auch immer, die Sache mit der Deliminierung scheint noch nicht so ganz zu klappen... Momentan wird für jedes >> eine ganze Zeile eingelesen, nicht bloss bis zum nächsten Komma. Woran könnte das liegen?
Der operator>>(std::string&) liest bis zum nächsten Leerraumzeichen (Newline, Space, Tab etc.). Du müßtest std::istream::ignore und std::getline verwenden.

Gruß

PS: Warum verwendest du denn Code Tags für Zitate? :confused:
 
Oder man muss halt nachschauen wo die Klassen, Funktionen etc. deklariert sind.

Das lässt immer noch das Problem das ich nicht eindeutig erkenne ob der Header nun eine standardbibliothek ist oder nicht... nun ja, ich werd wohl klüger werden mit der Zeit.

Der operator>>(std::string&) liest bis zum nächsten Leerraumzeichen (Newline, Space, Tab etc.). Du müßtest std::istream::ignore und std::getline verwenden.

Ah! Bingo, funktioniert. Vielen Dank!

PS: Warum verwendest du denn Code Tags für Zitate?

Ooops... war nicht absichtlich.
 
Hmmm... theoretisch funktioniert jetzt zwar alles, ich kriege aber einen sehr unorthodoxen Fehler beim Ausführen...

Der code sieht im Moment so aus:

Code:
	string Text1;
	string Nope;
	long mCount = 0;
	char TempChar;

	*Stars = new ES_Star[150000];

	ifstream mInFile("hygxyz.txt");

	for( ; getline(mInFile, Text1, ','); ++mCount )		
	{						
		getline( mInFile, Nope, ',');		        
	    getline( mInFile, Nope, ',');		        
	    getline( mInFile, Nope, ',');		        
	    getline( mInFile, Nope, ',');		        
	    getline( mInFile, Nope, ',');		        
	    getline( mInFile, Text1, ',');
	         if (Text1 == "") Text1 = "noname";
		Stars[mCount]->Name = Text1;
      }

Es folgen noch einige leseanweisungen mehr, aber hier tritt das Problem auf: Ein Fehler beim Überladen der daten auf Stars[mCount]->Name. Zunächst hatte ich das Problem das ich direkt aus dem File in Stars übergeladen habe, was einen Fehler in iosfwd verursachte wenn Stars[]->Name = "" war (was häufig der Fall ist). Warum weiss ich nicht genau, aber das Problem habe ich wie oben gelöst. Jetzt kriege ich einen anderen Fehler in iosfwd, der geht folgendermassen:

Unhandled exception at 0x00474f9c in 04.Movement.exe: 0xC0000005: Access violation writing location 0xa1a22ac0.

in dieser Funktion:

Code:
	static _Elem *__CLRCALL_OR_CDECL _Copy_s(_Elem *_First1, size_t _Size_in_bytes, const _Elem *_First2,
		size_t _Count)
		{	// copy [_First1, _First1 + _Count) to [_First2, ...)
//		_DEBUG_POINTER(_First1);
//		_DEBUG_POINTER(_First2);
		_CRT_SECURE_MEMCPY(_First1, _Size_in_bytes, _First2, _Count);
		return _First1;
		}

Meine Kentnisse reichen nicht mehr aus um festzustellen was genau hier schiefgeht. Interessant ist dass der Fehler nie in der ersten iteration auftritt, aber zuverlässig immer in der zweiten. Ich dachte erst das könnte an der grösse meines Arrays liegen, aber der Fehler tritt auch auf wenn ich das Array auf 4 beschränke. Irgendwelche Ideen?

wenn ich die Zeile mit dem überladen auskommentiere funktioniert alles wie am Schnürchen, der Fehler muss also etwas mit der überladung oder mit dem Typ ES_Stars zu tun haben. Die typendefinition lautet wie folgt:

Code:
struct ES_Star
{
	std::string Name;
	float Magnitude;
	std::string Spectrum;
	int Fraction;
	std::string Sequence;
	double x;
	double y;
	double z;
	double Distance;
};
 
Zuletzt bearbeitet:
Hi.

Was meinst du denn mit "Überladen"?

Du solltest mal die Grenzen des Arrays überprüfen. Du versuchst möglicherweise über die Grenze hinaus auf ein nicht-existierendes Element zuzugreifen.

Nutze den Debugger. Was ist der Wert der mCount Variablen wenn der Fehler auftritt?

\edit: Du solltest evlt. besser eine std::list oder einen std::vector
verwenden.

Gruß
 
Wie gesagt, der Fehler tritt bei der 2. Iteration auf, also wenn mCount = 1 ist.

Was meinst du denn mit "Überladen"?

Vielleicht nicht der richtige Ausdruck. Will sagen, wenn ich den String von Text1 and Stars[mCount]->Name weitergebe.

Werde es mal mit einer List versuchen (noch nie verwendet, aber laut der Referenz scheint das im Endeffekt besser geeignet für meinen Zweck als ein blosses Array).
 

Neue Beiträge

Zurück