String zerteilen / aufsplitten



  • tagchen...
    habe ma sicherlich ne anfängerfrage, wie immer... 😉
    lese aus ner Textdatei zeilenweise strings heraus.
    bsp: 1,name,adresse.... etc..
    nun möchte ich aber mittels einer funktion die durch komma getrennten daten so aufsplitten, dass ich die einzelnen werte bekomme, die ich in ne db eintragen kann. ich hatte an sowas wie explode (ist bei php so) gedacht. aber bisher habe ich nichts gefunden, was mir wirklich weiter hilft.
    ich hoffe ihr könnt mir helfen und DANKE schonmal im voraus.
    THX a lot.
    cu wasa



  • schau dich mal die funktionen find(), left() und right() an

    von einer richtung bis zum , suchen und kopieren, dann den rest in ein neues kopieren
    das so lange wiederholen bis kein , mehr gefunden wird

    das kannst du von rechts oder links machen - fuer beispielcode bin ich grad zu mued #gg



  • Vielleicht AfxExtractSubString(), ist aber leider undokumentiert. Zu finden in winstr.h

    BOOL AFXAPI AfxExtractSubString(CString& rString, LPCTSTR lpszFullString, int iSubString, TCHAR chSep);
    


  • undocumentiert {o;

    ich glaub nicht das des ist was er braucht, sein inhalt ist ja dynamisch, er kann ja nicht nach nen teilstring suchen ohne diesen zu kennen - und fuer teilstring suchen gibts shcon andere funktionen

    ich denk mir ein "abarbeiten" ist genau das was er braucht
    also von links nach rechts immer bis zum komma in eine dynamisch grosse variable den teilstring kopieren



  • Folgende Funktion sollte dies tun

    void SplitString(const CString& sInput, const CString& sDelimiter, CStringArray& saOutput)
    {
        long start = 0, 
        delim = sInput.Find(sDelimiter),
        delimLen = sDelimiter.GetLength(),
        elemCnt = 1; // the ACTUAL number of items, there'll be at least 1
    
        // counting the elements, setting the size and then filling the array 
        // is much faster than doing .Add for each new element
    
        while (delim > -1)
        {
            elemCnt++;
            start = delim + delimLen;
            delim = sInput.Find(sDelimiter, start);
        }
    
        // manually going through and finding each sDelimiter again is faster than 
        // keeping track of the positions from the last loop.. because doing .Add over and over 
        // to the position array would be such a bottleneck
    
        start = 0;
        delim = sInput.Find(sDelimiter);
        saOutput.RemoveAll(); //remove old elements
        saOutput.SetSize(elemCnt); // now we don't have to use .Add, saving tons of cpu cycles
        elemCnt = -1;
    
        while (delim > -1)
        {
            elemCnt++;
            saOutput[elemCnt] = sInput.Mid(start, delim-start);
            start = delim + delimLen;
            delim = sInput.Find(sDelimiter, start);
        }
    
        if (start < sInput.GetLength())
            saOutput[elemCnt+1] = sInput.Mid(start);
        else
            saOutput[elemCnt+1] = "";
    }
    

    gruss
    Marcus



  • Hallo Forum,
    hab gerade die

    BOOL AFXAPI AfxExtractSubString(CString& rString, LPCTSTR lpszFullString, int iSubString, TCHAR chSep);

    ausprobiert, garnicht schlecht, solangen in dem String der zu splittern ist
    der Trenner nicht in dem Teilstrings vorkommt, da trennt die Funktion
    gnadenlos ab!

    lg
    pixel



  • das wuerden die anderen funktionen doch auch, da ja nach diesem trennzeichen gesucht wird



  • ich tue die string in schleife und mit switch steure ich die werte die ich brauche.



  • MSDN schrieb:

    CStringT::Tokenize
    Finds the next token in a target string

    CStringT Tokenize(
    PCXSTR pszTokens,
    int& iStart
    ) const;

    Noch fragen? 🕶



  • tagchen...
    erstmal danke für eure vielen hinweise und tips.
    habe das jetzt wie folgt gehandhabt.

    CString pfad_gesamt = "zwischen\\austausch.txt"; 
    CStdioFile File; 
    
    if (File.Open(_T(pfad_gesamt), CFile::modeRead)) 
    { 
        CString strText, strResult,s_text, test; 
        int aufsplitten;
        CString dateiname, tester; 
        int a, l, b, c, d, test_l, w;
        CString daten[100];
    
        while(File.ReadString(strText)) 
        { 
    	if (dateiname.IsEmpty()) // die erste Zeile 
    	{ 
               s_text.Format("%s", strText);
    	  DatenEintrag(s_text);
    	  c=0;
    	  // Standard 12 Kommas 
    	 for (a=0; a<12; a++)
    	 {
    	    dateiname = strText;
    	    tester="";
    	    test="";
    	    l=strlen(dateiname);	// Länge des Strings
    	    aufsplitten=strText.Find(','); // stelle wo komma gefunden.
    	    for (b=c; b<=aufsplitten; b++)
    	    {
    	       test=test+dateiname[b];
    	    }
    	    s_text.Format("%s", test);
    	    DatenEintrag(s_text);
    
                 for (d=b; d<l; d++)
    	    {
    	      tester=tester+dateiname[d];
    	    }
    	    w=strlen(test);
    	    for (test_l=0; test_l<w-1; test_l++)
    	    {
    		daten[a]=daten[a]+test[test_l];
    	    }
    	    strText=tester;
    
    	} 
    	s_text.Format("%s", daten[0]);
    	DatenEintrag(s_text);
    
    	CSaugenSet rs; 
    	rs.Open(CRecordset::forwardOnly,"INSERT INTO customer VALUES ('"+daten[0]+"','"+daten[1]+"','12','12','12','12','12','12','12','12','12','12','12','12','12')",CRecordset::executeDirect); 
    
          } 
          else 
          { 
            // Zeilen 2 - ...				
          } 		
      } 
    }
    

    ist zwar sicherlich umständlich aber es funktioniert. die variablen etc werden alle noch umbenannt, dieses script diente nur zu testzwecken.
    der ursprungsstring sieht ungefähr so aus:

    nachname,tester,tester,tester,tesre,00000,tester,014789654,123456789,irgendwas@irgendwo.de,keine ahnung,,

    ich habe nur noch ein problem.
    und zwar will ich jetzt die einzelnen daten in ne db schreiben.
    aber da bringt der mir ne fehlermeldung:
    "You hav an SQL Syntax error...."
    wisst ihr vielleicht was ich da falsch mache?!
    Danke schonmal für eure hilfe und Mühe.
    THX a lot.
    bartholomeus



  • 1.) Musst du nicht die Spaltennamen angeben?
    2.) Zeichenketten gehören in einzelne Anführungszeichen.



  • 1.) Musst du nicht die Spaltennamen angeben?
    2.) Zeichenketten gehören in einzelne Anführungszeichen.

    mhm...
    zu 1. ich kenne es nicht so. bei nem INSERT INTO gibt man keine spaltenname an. Man muss nur darauf achten, die Anzahl einzuhalten. oder sehe ich das falsch?

    zu 2. wie jetzt. laut meinem beispiel müsste ich dann was schreiben?
    Insert into ... values ('+daten[0]+',....) ????

    ich werd mal schauen ob ich das hinbekomme!
    danke erstmal
    bartholomeus



  • Hallo,
    @Bart, könntest du eine Zeile aus deiner Datei posten, Du kannst natürlich die echten Werte mit Beispielwerten ersetzen!
    Hast gesagt die Werte sind mit Komma getrennt, eine *.csv Datei?
    Mich würde der genaue Satzaufbau interesieren.
    Ich meine das man die Zeilen wenn sie schon mit Komma getrennt sind auch einfacher zerlegen kann!? 🙄

    lg
    pixel



  • tagchen...

    @Bart, könntest du eine Zeile aus deiner Datei posten, Du kannst natürlich die echten Werte mit Beispielwerten ersetzen!

    also:
    "nachname,tester,tester,tester,tesre,00000,tester,014789654,123456789,irgendwas@irgendwo.de,keine ahnung,,"
    sowas steht in meiner txt datei drin... und das zeilenweise....

    Ich meine das man die Zeilen wenn sie schon mit Komma getrennt sind auch einfacher zerlegen kann!?

    Sicherlich kann man das einfacher machen, wie ich das gemacht habe. Dasproblem ist, ich bin anfänger auf dem gebiet der c++ / MFC von daher bin ich froh das es funktioniert. auch wenn es nicht die feine englische art ist.

    aber kannst du mir vielleicht helfen wie ich den sql error beseitige?
    thx a lot
    cu bartholomeus



  • Hallo,

    hab gerade nachgeschaut, eigendlich sollen die spalten namen schon mit angegeben werden??!!!

    // Use a VALUES clause to specify the data values for one row: 
    INSERT INTO MyTable (PriKey, Description)
           VALUES (123, 'A description of part 123.')
    

    cu
    pixel



  • Möglicherweise mag er das INSERT direkt im Open-Befehl nicht. Laut MSDN kannste bei CRecordset::Open nur ein SELECT-Statement mitschicken.



  • Ich hab das jetzt nicht mehr so präsent, aber kann man bei forwardonly überhaupt ein INSERT ausführen?



  • tagchen...
    also habe jetzt auch die spaltennamen nochmal mit hinzugefügt, trotzdem kein erfolg.
    desweiteren habe ich das forwardonly ersetzt:
    dynaset, snapshot, forwardOnly, dynamic
    funktioniert aber auch nicht. bzw bei dynaset kommt, das der treiber nicht unterstützt wird...

    irgendwie komm ich hier absolut nicht weiter, und weiß nicht was ich noch machen kann..
    hoffe ihr könnt helfen und bedanke mich schonmal
    thx a lot
    cu bartholomeus



  • Hallo,
    warum glaubst du das daten[0] in die doppelten hochkommas muessen?
    Hast versucht die mal weg zu nehmen, so das nur die Variable steht, also in den einfachen hochkommas? 😕
    Versuchs mal ohne:

    //INSERT INTO customer VALUES ('"+daten[0]+"','"+daten[1]+",...);
    INSERT INTO customer VALUES ('+daten[0]+','+daten[1]+',...);
    

    lg



  • ja das habe ich auch schon gemacht. funktioniert nicht. das mit den Hochkommas oder anführungszeichen habe ich versehentlich aus php übernommen, da das eigentlich mein gebiet ist.. naja..

    ich habe es anders gemacht aber immer noch einen fehler:

    CSaugenSet rs; 
    rs.Open(CRecordset::snapshot,NULL,CRecordset::appendOnly); 
    
    rs.AddNew();
    rs.m_c_id = daten[1];
    rs.m_c_vorname = daten[1];
    rs.m_c_nachname=daten[2];
    rs.m_c_strasse = daten[3];
    rs.m_c_hnr=daten[4];
    rs.m_c_plz=daten[5];
    rs.m_c_ort=daten[6];
    rs.m_c_telefon=daten[7];
    rs.m_c_telefax=daten[8];
    rs.m_c_email=daten[9];
    rs.m_c_land=daten[10];
    rs.m_c_bank=daten[11];
    rs.m_c_konto=daten[12];
    rs.m_c_blz=daten[13];
    rs.m_l_user=daten[14];
    rs.Update();
    

    habe es mit snapshot versucht zu öffnen. dabei kommt folgende fehlermeldung:
    "Datensatzgruppe kann nur gelesen werden"

    wie bekomm ich das weg???
    danke nochmal... und sorry das ich soviel nerve...


Anmelden zum Antworten