While Schleife - Zeichenkette anhängen (char, char*, feste Länge,.. ??)



  • hi!
    ja hab bereits auch festgestellt das char[512] ein char-array ist.. und ich wie in php auch mit [0] etc. drauf zugreifen kann (oder in einer for schleife durchlaufen)..

    ein vektor ist also ein dynamisches array welches sich in der größe automatisch dem inhalt anpasst?

    und ferne nehme ich an das ich auch per output[0] auf den vektor zugreifen kann..

    jedoch gibt er mir hier ein "seltsamen fehler" zurück..

    int c;
       char buffer[512];
       vector<string> output;
       //char output[];
    
       while ((c = recv(new_socket, buffer, 512, 0)) > 0) {
         buffer[c] = 0;
         //printf("%s", buffer);
    
         string tmp = buffer;
         output.push_back(tmp);
       }
       //Content-Length auswerten und mit variable vergleichen
    
       //Header abschneiden
    
       //output splitten
    
       printf("%s",output[1]);
    

    und der fehler:

    C:/statwriter/main.cpp:94: warning: cannot pass objects of non-POD type 'struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >' through '...'; call will abort at runtime

    außerdem meckert er bei printf das output int wäre ??.. (ist doch jetzt aber ein vektor, richtig? oder immernoch ein char array ?? aber auf jedenfall kein INT )

    C:/statwriter/main.cpp:94: warning: format '%s' expects type 'char*', but argument 2 has type 'int'

    was das splitten von vektoren angeht habe ich diese gute seite gefundenhttp://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-7.html
    damit könnte ich ja dann den vektor anhand eines trennzeichens teilen

    Zur Info:
    Ich bekomme vom Server den Header und verschiedene werte (sagen wir kommagetrennt)
    wert1,wert2,.....
    die werte kommen dann in eine mysql datenbank...
    d.h. output[0] = wert1;
    output[1] = wert2;
    usw. in die jeweiligen datenbankfelder...



  • Die printf-Anweisung muss so aussehen:

    printf("%s",output[1].c_str());
    

    So wird der String in ein C-String umgewandelt.

    MfG, Jochen



  • wahhhnsinn, danke!! jetzt weiß ich auch was das c_Str() macht 😉

    d.h also "output" direkt nach der while schleife ein string und ich kann ihn mit den string/vector funktionen bearbeiten... ? bzw was ist der unterschied zum c-string?

    EDIT: ach ist das toll 😉 danke, danke danke! jetzt fühl ich mit dem substr und strpos ja schon richtig heimisch ^^

    hab mein letzen beitrag überarbeitet.. (damit du weißt was ich überhaupt vorhab 😉



  • frage nach c-string hat sich mittlerweile erübrigt 😉

    eine kleinigkeit hätte ich aber noch (wo ich einfach nicht verstehe warum ein zeichen fehlt...)

    content beinhaltet:
    "1,2,3,4,5,6,7,8,9,0,1,2" also 23 zeichen, nach dem cut sollten es 12 sein
    fin_out.size() ist 11 (size zählt auch von 0 an richtig?)

    soweit so gut.
    gebe ich nun fin_out[11] aus gibt er mir ein NULL zurück.
    fin_out[10] ist 1, bis hierhin also alles OK. nur fehlt nun eben die 2...

    hab ich bei der splitstring funktion einen fehler eingebaut? oder wer kann mir das misteriöse verschwinden der 2 erklären 😉

    bei fin_out[12] stürzt mir übrigens das programm ab(nicht die windof konsole 😉 ) ... ich nehme an weil es fin_out[12] ja auch gar nicht gibt, richtig?

    schonmal vielen vielen dank für eure hilfe 😉

    zum besseren verständnis noch ein auschnitt der funktion und der ausgabe..

    //String Split
     vector<string> stringsplit(char search, string val) {
    
        string tmp = "";
        vector<string> result;
    
        for(unsigned short i = 0; i <= val.size(); i++){
    
            if(val[i] == search)
            {
                result.push_back(tmp);
                tmp = "";
            } else {
                tmp += val[i];
            }
        }
    
     return result;
     }
    
     /* END FUNCTIONS */
    
    //........
    
       //Splitting output in "Header" and "Content"
       string::size_type pos = output[0].find("\r\n\r\n");
       printf("\nPosition: %d\n\n", pos);
       string header = output[0].substr(0,pos);
       string content = output[0].substr(pos+4);
    
       //TMP print Header and Content
       printf("Header:\n%s\n\n",header.c_str());
       printf("Content:\n%s\n\n",content.c_str());
    
       //TMP Conten Size
       int consize;
       consize = content.size();
       printf("Size of Content String: %d\n\n", consize);
    
       //Split Content
       vector<string> fin_out;
       fin_out = stringsplit(',', content);
    
       //TMP fin_out Size
       int vecsize;
       vecsize =fin_out.size();
       printf("Size of cutted fin_out String: %d\n\n",vecsize);
    
       //Listing of fin_out elements..
       for(unsigned short i = 0; i <= vecsize; i++)
       printf("Stelle %d: %s\n",i, fin_out[i].c_str());
    
       //vector <int>::size_type fin_out_size;
       //fin_out_size = fin_out.size();
    
       //printf("%u\n", fin_out_size);
    
       closesocket(new_socket);
       WSACleanup();
       return 0;
     }
    

  • Administrator

    1. Der Header <stdio.h> heisst in C++ <cstdio> . Dann liegt auch alles im Namensraum std .
    2. Wieso verwendest du printf ? In C++ gibt es dazu std::cout aus <iostream> . Da kannst du auch gleich einen std::string übergeben:

    #include <string>
    #include <iostream>
    
    int main()
    {
      std::string hello = "hello";
      std::cout << hello << std::endl;
    }
    

    3. Die Indices gehen immer von 0 bis size -1. Du greifst aber an mehreren Orten auf das Element an der Stelle size zu, was undefiniertes Verhalten ist. Schau dir vor allem deine for -Schleifen an.
    4. Deine stringsplit Funktion ignoriert den letzten Teil. Du fügst ja immer nur etwas in deinen temporären std::vector , wenn du ein Komma findest. Nach der 2 am Ende hat es aber kein Komma, somit wird diese Zahl nie in den Container kommen.
    5. Ich bevorzuge die erstere Referenz:
    http://www.cplusplus.com/reference/
    http://www.cppreference.com/wiki/
    6. Am meisten bevorzuge ich aber Bücher als Referenzen. Würde ich dir auch dringend zu raten.
    Da dein erster Code extrem nach C aussieht, bist du womöglich ein Umsteiger? Dann hier hin: http://www.c-plusplus.net/forum/viewtopic-var-t-is-265356.html
    Ansonsten kauf dir ein Buch wie den C++ Primer oder falls Englisch nichts ausmacht, gibt es auch noch Thinking in C++ 1&2 (gibt es als Gratis Download).

    Grüssli



  • zu 6. ich bin php umsteiger 😉
    ich zitiere mal von einem anderen thread was einer auf die frage "unterschied zw c++ und c" gesagt hat

    Wenn Du C++ lernen willst kommst Du an C nicht vorbei (Du lernst es halt mit).

    deswegen wohl die mischung aus c++ und c 😉

    zu5. Danke! die erste kannte ich schon, wobei mir die erste auch sympathischer vorkommt 😉

    zu2. weil mit der iostream library meine exe (als release) von 88kb auf 470kb wächst... (und ich das programm gerne schön klein hätte 🙂 ) außerdem.. was spricht gegen printf?

    zu3 das verstehe ich jetzt nicht ganz.. size(fin_out) ist doch 11? (12 zeichen... also 0,1,2,3,4...,11)
    und drauf zugreifen tu ich dann von fin_out[0] bis fin_out[11] ??

    zu4. stimmt, denkfehler das muss ich wohl umschreiben...

    wenn du willst kann ich dir auch gerne den kompletten code zeigen und du sagst mir was du davon hälst 🙂


  • Administrator

    taurus schrieb:

    zu 6. ich bin php umsteiger 😉
    ich zitiere mal von einem anderen thread was einer auf die frage "unterschied zw c++ und c" gesagt hat

    Wenn Du C++ lernen willst kommst Du an C nicht vorbei (Du lernst es halt mit).

    deswegen wohl die mischung aus c++ und c 😉

    Das war so allerdings nicht gemeint. Konzentriere dich lieber zuerst auf die C++ Möglichkeiten. C sollte man nur dort reinnehmen, wo man genau weiss, was man macht. Ein Anfänger weiss dies aber meistens noch nicht.

    taurus schrieb:

    zu2. weil mit der iostream library meine exe (als release) von 88kb auf 470kb wächst... (und ich das programm gerne schön klein hätte 🙂 ) außerdem.. was spricht gegen printf?

    printf ist nicht typsicher und kann keine eigenen Typen unterstützen. Zudem besteht die Gefahr eines Überlaufes. Grundsätzlich hast du das Problem sogar in diesem Thread schon selber gesehen, als du den std::string an printf übergeben wolltest. Zum Glück hat dein Kompiler dich gewarnt, hätte es aber nicht tun müssen. Komplieren tut es dann auch, nur das Resultat ist undefiniert. An solchen Fehlern sitzt man dann auch meistens etwas länger. Wenn std::cout einen Typ nicht kennt und/oder ihn nicht ausgeben kann, gibt es einen Kompilerfehler. Die Gefahr von undefiniertem Verhalten hast du somit nicht.

    taurus schrieb:

    zu3 das verstehe ich jetzt nicht ganz.. size(fin_out) ist doch 11? (12 zeichen... also 0,1,2,3,4...,11)
    und drauf zugreifen tu ich dann von fin_out[0] bis fin_out[11] ??

    Nein. Wenn dir jemand sagt, dass du 11 Zeichen hast, wie kommst du dann bitte auf die Idee, dass du 12 Zeichen hast?
    Es wird dir ganz klar gesagt, dass du eine Grösse von 11 hast, also 11 Zeichen. Somit müssen deine Indices von 0 bis 10 gehen, weil es eben 11 Zeichen sind. Steht aber in jedem Grundlagenbuch 😉

    taurus schrieb:

    wenn du willst kann ich dir auch gerne den kompletten code zeigen und du sagst mir was du davon hälst 🙂

    Kannst du machen, aber erwarte nicht, dass eine Antwort kommt. Für eine komplette Codeanalyse (von nur ein paar 100 Zeilen) kann man schon mal 1-3 Stunden investieren. Soviel am Stück liegende freie Zeit habe ich gerade nicht. Und oft fehlt einem auch einfach die Lust dazu, sowas zu machen. Ist nicht gerade eine tolle Arbeit 😉

    Grüssli



  • Kannst du machen, aber erwarte nicht, dass eine Antwort kommt. Für eine komplette Codeanalyse (von nur ein paar 100 Zeilen) kann man schon mal 1-3 Stunden investieren. Soviel am Stück liegende freie Zeit habe ich gerade nicht. Und oft fehlt einem auch einfach die Lust dazu, sowas zu machen. Ist nicht gerade eine tolle Arbeit 😉

    stimmt 😉 vor allem weil man ja erstmal vertehen muss was der herr da geschrieben hat 😉

    Nein. Wenn dir jemand sagt, dass du 11 Zeichen hast, wie kommst du dann bitte auf die Idee, dass du 12 Zeichen hast?
    Es wird dir ganz klar gesagt, dass du eine Grösse von 11 hast, also 11 Zeichen. Somit müssen deine Indices von 0 bis 10 gehen, weil es eben 11 Zeichen sind. Steht aber in jedem Grundlagenbuch 😉

    ja ich übersah die funktion und dachte mir die größe fängt bei 0 an ^^ aber das problem sehe ich gerade.. liegt alles an der funktion...

    printf ist nicht typsicher und kann keine eigenen Typen unterstützen.

    also von grundauf auf printf verzichten. wobei gibt es keine möglichkeit die iostream abzuspecken? von 88kb auf 470kb ist ja schon enorm...
    in der library steckt soviel das ich ja gar nicht benötige...

    Das war so allerdings nicht gemeint. Konzentriere dich lieber zuerst auf die C++ Möglichkeiten

    gibt es denn eine übersicht die gegenüberstellt wie der synthax in c oder in c++ aussieht? ob eine funktion c oder c++ ist kann ich ja in den referenzen nachlesen...
    werde das auch gleich nochmal googlen... erstmal frühstück, gehirnnahrung 😉

    grüße
    felix


  • Administrator

    taurus schrieb:

    also von grundauf auf printf verzichten. wobei gibt es keine möglichkeit die iostream abzuspecken? von 88kb auf 470kb ist ja schon enorm...
    in der library steckt soviel das ich ja gar nicht benötige...

    Verschiedene Dinge hierzu:
    1. Was stört dich an der Grösse? Heutzutage haben wir Computer mit mehreren Terabytes an Speicher ...
    2. Du kann den Kompiler wechseln, sowas ist oft auch von diesem abhängig. Hast du zudem in einer Release Version kompiliert? Man kann zum Beispiel auch auf die Grösse hin kompilieren, wobei ich noch nie gehört habe, dass dies jemand gemacht hat. Aber allgemein Optimierungen durchführen lassen, dürft auch schon was helfen.
    3. Du kannst dynamisch zur Standardbibliothek linken. Dann musst du diese aber als Library mitliefern. Aber falls mehrere Programme die Library benötigen, muss dies natürlich nur einmal auf dem System vorhanden sein.

    taurus schrieb:

    gibt es denn eine übersicht die gegenüberstellt wie der synthax in c oder in c++ aussieht? ob eine funktion c oder c++ ist kann ich ja in den referenzen nachlesen...

    Schwierig, da die Syntax von C und C++ sehr ähnlich bis gleich ist. Aber es geht mehr darum, dass man mehr Möglichkeiten hat, sich das Leben zu erleichtern in C++. Es geht um die Programmierkonzepte. Erfährst du aber alles in einem guten Lehrbuch 😉

    Grüssli



  • abgesehen vom speicherplatz sind 80kbyte mehr arbeitsspeicher durch die iostream genutzt...
    ok ändert sich vielleicht wenn ich printf entferne und die cstdlib entferne...

    naja ich find halt auch das für so ein kleines programm 500kb einfach viel sind 🙂

    habs als release kompiliert, richtig.
    zu pkt 3 wenn es egal ist ob das programm jetzt 500 oder 100kb groß ist (also von der performance, arbeitsspeicher her) dann lass ich es mit iostream und gut..

    ein c++ buch wirds wohl bald wieder geben.. (als ich 15 war wollt ichs mal anfangen.. aber nunja daraus wurde nichts 😉 hatte mir damals c++ für dummies gekauft.. wo das buch jetzt ist weiß ich nicht, die cds hab ich aber noch 😉



  • 3. Die Indices gehen immer von 0 bis size-1. Du greifst aber an mehreren Orten auf das Element an der Stelle size zu, was undefiniertes Verhalten ist. Schau dir vor allem deine for-Schleifen an.

    um hier nochmal drauf zurückzukommen.

    //TMP fin_out Size
       int vecsize;
       vecsize =fin_out.size();
       printf("Size of cutted fin_out String: %d\n\n",vecsize);
    
       //Listing of fin_out elements..
       if(vecsize != 0) {
       for(unsigned short i = 0; i < vecsize; i++)
       printf("Stelle %d: %s\n",i, fin_out[i].c_str());
       }
    

    die indices fangen hier ja bei 0 an und gehen bis 10 (bei einer size größe von 11)
    so ist das ja i.O. und kein undefiniertes verhalten?

    vorher hatte ich ja ein "i <= vecsize" drin was natürlich falsch ist..



  • So ist es Korrekt.
    Noch eine Anmerkung: Die if-Bedingung kannst du weglassen, da die Schleife gar nicht erst ausgeführt wird, wenn vecsize 0 ist. Die Bedingung wird nämlich immer geprüft, bevor der Anweisungsteil ausgeführt ist.



  • logisch ^^ das kommt davon wenn man keine pause macht und bis in die nacht arbeitet 🙂


Anmelden zum Antworten