strtok()



  • Hallo,
    folgendes Stück Code:

    int main(){
      char test[] = "Das\n\nist\nmanl\nein\n\nTest";
      char* row = strtok(test, "\n");
      if(row != NULL){
        do{
          cout << row << endl;
        }while((row = strtok(NULL, "\n")) != NULL);
      }
    }
    

    Die von mir erwartete Ausgabe sollte so aussehen:

    Das
    
    ist
    nmanl
    ein
    
    Test
    

    Die tatsächliche Ausgabe schaut aber zu meiner Enttäuschung so aus:

    Das
    ist
    nmanl
    ein
    Test
    

    Ich möchtle also die Leerzeilen auch als Token...
    Weiß jemand wieso bzw einen Workaround für dieses Problem.
    Ich bin auf ANSI C beschränkt also bitte nix andres...

    Danke und Gruß

    Demoncleaner



  • Es gibt in Strings keine Leerzeilen. Ein String besteht aus Zeichen und wenn das zwei Zeilenvorschübe drin sind, die du als Separator festgelegt hast, so werden dort die Strings auch getrennt und die Zeilenvorschübe in beliebiger Anzahl ignoriert.



  • Hast dun Vorschlag wie mans eventuell umgehen bzw
    lösen koennte?

    Gruß

    RedWing



  • Legst du den Text denn selbst fest? Wenn ja musst du einfach ein anderes Trennzeichen verwenden wie zum Beispiel ein Leerzeichen



  • Nein der Text ist eine html Seite die ausm Internet kommt.
    Ich muss diese 1zu 1 in einem Vektor speichern...
    Sprich wenn die html Datei 3 Zeilen hat und davon sind 2 Leerzeilen dabei
    sollte der Vektor auch 3 groß sein...
    Mein Code sieht bis jetzt so aus nur wioe gesagt funktioniert er bei
    Leerzeilen leider nicht:

    char* copyOfSource = (char*)nsMemory::Clone(m_source.get(), m_source.Length() + 1);
      char* currentLine = strtok(copyOfSource, "\n");
      if(currentLine != nsnull){
        do{
          m_sourceLines.Add(nsEmbedCString(currentLine));
        }while((currentLine = strtok(nsnull, "\n")) != nsnull);
      }
      nsMemory::Free(copyOfSource);
    

    Danke und Gruß

    RedWing



  • Demoncleaner schrieb:

    Ich bin auf ANSI C beschränkt also bitte nix andres...

    habe ich was verpasst ?? oder seit wann darf man das schon in c benutzen...

    Demoncleaner schrieb:

    cout << row << endl;
    


  • icepacker schrieb:

    Demoncleaner schrieb:

    Ich bin auf ANSI C beschränkt also bitte nix andres...

    habe ich was verpasst ?? oder seit wann darf man das schon in c benutzen...

    Demoncleaner schrieb:

    cout << row << endl;
    

    Das cout ist vollkommen nebensächlich und dient nur zu Testzwecken.
    Wenn ich ANSI C meine meine ich damit die Funktionen die die ANSI C Library
    zur Verfügunug stellt um meine Aufgabe bzw mein Problem zu lösen.
    Wie ich das ausgebe (da die Ausgabe eh nur zu Testzwecken ist) ist vollkommen
    nebensächlich...

    Gruß

    RedWing



  • Für das was du machen willst ist strtok nicht geeignet, weil es die Trennzeichen eben ignoriert und nur Strings aus Nicht-Trennzeichen dazwischen zurückliefert. Wenn ich das richtig verstanden habe und du willst die Zeilen einfach einzeln in deinem objektorientierten ANSI C-Stringvektor 🙂 speichern, solltest du mit strchr das nächste Vorkommen des Zeilenvorschubs suchen und den String von Startposition bis zum Zeilenvorschub in den Vektor tun. Und danach die Position hinter dem Zeilenvorschub als neue Startposition festlegen und wieder mit strchr nach dem nächsten Zeilenvorschub suchen. Eine Leerzeile ist dann einfach nur ein String, der ein einzelnes \n enthält (und Terminierung natürlich)



  • int main(){
      char test[] = "Das\n\nist\nmanl\nein\n\nTest";
      char* row = test;
      char* newRow = row;
      while((newRow = strstr(row, "\n")) != NULL){
        if(newRow - row > 0){
          char line[newRow - row + 1];
          strncpy(line, row, newRow - row);
          line[newRow - row] = 0;
          cout << line << endl;
        }
        else cout << endl;
        row = newRow + 1;
        if(strstr(row, "\n") == NULL ) cout << row << endl;
      }
    }
    

    Ich habs jetzt so gemacht. Und für die dies ganz genau nehmen
    das cout lässt sich auch durch ein printf ersetzen und das Array was
    angelegt wird in der schleife kann man auch als Zeiger nach der
    Funktionsignatur anlegen und diesen mit malloc jedesmal neu allokalisieren...
    Das für die Haarspalter 🙂

    Wenn ich das richtig verstanden habe und du willst die Zeilen einfach einzeln in deinem objektorientierten ANSI C-Stringvektor 🙂 speichern,

    Also die Problematik ist folgende.
    Ich bin an ein Framework gebunden was in C++ geschreiben ist. Deswegen
    kann ich auch in C++ programmieren. Ich bentuze nur die Funktionen des
    Frameworks und ANSI C Funktionen da ich mir bei diesen sicher sein kann
    das die glibc bzw das Windowsäquivalent auf jedem Zielrechner installiert ist.
    Bei der libstdc++ schaut das schon wieder anders aus(denk ich zumindest,
    wenn ich mich irre bitte berichtigen das würde mir dann sicherheit bringen
    und ich bräuchte mich nicht mehr mit C rumzuquälen :))
    Jetzt sollten dann wohl alle Ungereimtheiten geklärt sein 🙂

    @masterofx32 Vielen Dank für deine Hilfe...

    Gruß

    Demoncleaner...


Anmelden zum Antworten