Problem mit CString aus Datei einlesen
-
hallo,
mit folgendem Code möchte ich einzelne Werte aus einer Zeile isolieren:
if(File.Open("Lager.csv", CFile::modeRead)) //Öffnen von Lager.csv im Read Modus { while(File.ReadString(CString_hlp)) { Produktnr++; Produktname[Produktnr] = CString_hlp.Left(CString_hlp.Find(",",0)); CString_hlp.Replace(Produktname[Produktnr]+",",""); Kurzname[Produktnr] = CString_hlp.Left(CString_hlp.Find(",",0)); CString_hlp.Replace(Kurzname[Produktnr]+",",""); Bestellnr[Produktnr] = CString_hlp.Left(CString_hlp.Find(",",0)); CString_hlp.Replace(Bestellnr[Produktnr]+",","");
Das funktioniert soweit auch ganz gut, nur wenn einer der einzulesenden Strings leer ist (also 2 Trennzeichen (komma) aufeinander folgen) fängt er an rum zuspinnen und liest die werte nicht mehr richtig aus, bzw entfernt alle kommas die aufeinander folgen mit einmal, wie ich kann dem problem aus dem weg gehen?
mfg, TFTS
-
Vielleicht mit einem
if(CString_hlp != ",,")
am Anfang der Schleife ?
-
nein, das ergibt keinen sinn, wenn zum bsp mehrere werte hintereinander leer sind, folgen auch mehr als 2 kommas aufeinander
andere Lösungsvorschläge?
mfg, TFTS
-
Wie wäre das:
- eine neue CString-Variable erstellen
- in die neue Variable den Inhalt von CString_hlp rein kopieren
- bei der neuen Variablen ein Replace(",", "") machen
- gucken, ob die neue Variable jetzt leer ist
-
naja so ne holzfäller lösung hab ich auch, indem ich einfach beim schreiben der datei überprüfe ob werte mit "" vorhanden sind in diese dann mit " " ersetze... aber ich dachte, dass es vielleicht eine elegante lösung bzw. einen grund dafür gibt, warum er die ganzen kommas mit einmal replaced
mfg, TFTS
-
Hi Tom,
nachdem ich deinen Text nun zum 3. Mal gelesen habe, glaube ich verstanden zu haben, was du willst...
Kann dir aber erst heute Abend konkretes dazu sagen... also Geduld.
Übrigens: nur so als Tip:
ein Komma als Trennzeichen zu benutzen, ist nicht wirklich gut, stell dir einfach vor, der Produktname (ist ja ein String) enthält mal zufällig ein Komma... den folgenden Ärger kannst du dir ja vorstellen... ich nehm immer # oder | als Trennzeichen, ein [ oder ] kommt auch weniger oft vor...
Denk mal drüber nach!Greez
-
ja ich weiss was du meinst, aber wenn ich die csv datei in excel öffne wird standardmässig als trennzeichen nur ein komma aktzeptiert, und das jedesmal zu ändern wenn man excel öffnet ist auch nich das wahre...
Die Strings sollten kein Komma enthalten, soweit ich weiss
mfg, TFTS
-
Das er die Kommas ersetzt scheint logisch, weil das gibst du ja an.
Leer + , ==, und das ersetzt du mit "".
Dem holzfäller wirst du nicht auskommen.
Wenn doch hätte ich auch interesse daran
-
Ich schon wieder...
Noch eine Möglichkeit:
- zwei neue Integer-Variablen (z.B. hier einfach mal "erste" und "zweite" genannt). Die erste auf 0, die zweite auf CString_hlp.Find(",", erste) setzen
- nicht mit Left(...) den Teilstring auslesen und abschneiden sondern mit Mid(erste, zweite) und den String einfach so lassen
- erste den Wert von zweite zuweisen plus nächste Position (erste = zweite+1) und zweite wieder das nächste Komma suchen lassen: CString_hlp.Find(",", erste)
So ungefähr könnte es auch noch klappen.
-
Wie ist denn dieses File genau aufgebaut?
Du könntest auch mit string.GetAt(string.Find(',') + 2) abfragen ob nach dem Komma wieder ein Komma kommt? Wenn du mir jedoch zeigen könntest wie die Datei aufgebaut ist (also obs mehrere Zeilen sind und wies aussieht wenn nichts vorhanden ist etc) könnt ich versuchen was möglichst "kleines" zu machen...
-
die datei hat in etwa folgende struktur:
Zeile1,name1,lala1,huhu1,guguck1,ende1,
Zeile2,name2,,,ende2,die strings lala2,huhu2 bzw. guguck2 sind also leer und die kommas folgen demzufolge direkt aufeinander. und mein code entfernt halt an dieser stelle alle 3 kommas beim auslesen von dem (eigentlichen) "lala2"
ich hoffe es war halbwegs verständlich
danke schonmal für eure hilfe
mfg, TFTS
-
Hi,
ich habe eine ähnliche Funktion geschrieben um mir Daten aus einer Datei zu holen in der ich nach folgendem Schema schreibe:
SERVERNAME|USERNAME|PASSWORT|CRLF
SERVERNAME|USERNAME|PASSWORT|CRLFvoid CConnectionDlg::ReadServerList() { FILE *Stream; int nfsize=0; int nread=0; int nblocksize=1024; m_CmbList.ResetContent(); m_structsize=0; if ((Stream=fopen(m_defaultfilename,"r"))==NULL) { this->CreateNewDataFile(m_defaultfilename); } if (!(Stream=fopen(m_defaultfilename,"r"))==NULL) { CFtpFileInfo *pFtpFileInfo =(CFtpFileInfo*) new CFtpFileInfo; nfsize=pFtpFileInfo->GetTheFileSize(m_defaultfilename); char *pdata = (char *) new char[nfsize+1]; while (!feof(Stream)) { nread+=fread(pdata+nread,sizeof(char),nblocksize,Stream); } fclose(Stream); char crlf[2]="\n"; char pipe[2]="|"; char *endptr; char *curptr; char *pendptr; char pipedata[256]; char *ppipedata; int i=0, x=0; curptr=pdata; for (endptr=strstr(curptr,crlf);endptr!=NULL;endptr=strstr(curptr,crlf)) { *endptr='\0'; strcpy(pipedata,curptr); ppipedata=pipedata; for (pendptr=strstr(ppipedata,pipe);pendptr!=NULL;pendptr=strstr(ppipedata,pipe)) { *pendptr='\0'; switch (x) { case 0: strcpy(m_pstructlist[i].server,ppipedata); m_CmbList.InsertString(i,m_pstructlist[i].server); break; case 1: strcpy(m_pstructlist[i].username,ppipedata); break; case 2: strcpy(m_pstructlist[i].password,ppipedata); break; default: break; } ppipedata=pendptr + strlen(pipe); x++; } this->resizeStruct(1); curptr=endptr + strlen(crlf); m_CmbList.SetCurSel(i); UpdateCmbList(i); i++; x=0; } delete [] pdata; delete pFtpFileInfo; } else { MessageBox("Err: 55000: Cannot open File"); } }
Du musst halt die Teile wie FtpFileInfo und m_CmbList und m_pstructlist rausschmeissen.
Keine Gewähr, funktioniert bei mir zwar einwandfrei, habe jedoch erst mit maximal 20 Datensätzen getestet und bin blutiger Anfänger in c++.Bye
-
ich wollte eigentlich direkt CStrings auslesen und ich denke, dass das mit meiner variante schon ganz gut funktioniert so, bleibt halt nur das problem mit den kommas bzw. trennzeichen
mfg, TFTS
-
hallo,
mir ist gerade aufgefallen, dass es nicht an den leeren CStrings liegt, sondern allgeim daran, wenn mehrmals der gleiche String aufeinander folgt, wird immer nur der erste String gelesen zb:
hallo,du,du,du,wie,
ergibt dann
hallo,du,wie
nach dem einlesen
ich hab absolut keine ahnung wie es dazu kommt - ich hoffe es kann mir jmd helfen
mfg, TFTS
-
hab jetz selbst herausgefunden wo das problem lag, bei dem replace befehl werden natürlich alle zutreffenden strings ersetzt, wenn also der zu ersetzenden string mehrmals auftaucht wird er auch mehrmals ersetzt.
Umgehen kann man das Problem wie folgt
Firmenname1[Firmennr] = CString_hlp.Left(CString_hlp.Find(",",0)); int_hlp=Firmenname1[Firmennr].GetLength(); CString_hlp.Delete(0,int_hlp+1);
somit wird auch wirklich nur der forderste string gelöscht...
mfg, TFTS
-
Header
class parser { public: parser(void); ~parser(void); bool parseall(CString parsestring,CString searchstring,CStringArray &retarray,CString firstsearchstring); int counter; private: int pos; int lastpos; int laengelastsuchzeichen; };
cpp
#include "StdAfx.h" #include ".\parser.h" parser::parser(void) { pos = 0; lastpos = 0; laengelastsuchzeichen = 1; } parser::~parser(void) { } bool parser::parseall(CString parsestring,CString searchstring, CStringArray &retarray,CString firstsearchstring) { int count = -1; if (!firstsearchstring.IsEmpty()) { count = parsestring.Find(firstsearchstring,0); if (count == -1) { } else { retarray.Add(parsestring.Mid(0,count)); parsestring.Delete(0,count + firstsearchstring.GetLength()); parsestring.TrimLeft(); count = -1; } } do { count = parsestring.Find(searchstring,0); if (count == -1) { parsestring.TrimRight(); retarray.Add(parsestring); } else { retarray.Add(parsestring.Mid(0,count)); parsestring.Delete(0,count + searchstring.GetLength()); parsestring.TrimLeft(); } } while (count != -1); return true; }
Aufruf
parser parse; CStringArray retarray; CString line("hallo,du,du,du,wie,"); parse.parseall(line,",",retarray,","); retarray.ElementAt(x);