17 berichten aan het bekijken - 1 tot 17 (van in totaal 17)
  • Q:
    Bijdrager
    dj bazzie wazzie

    [C/C++]Command Line Arguments

    Wanneer ik een nieuwe C++ command line utility maak en daarbij de onderstaande code uitvoer en de executable als argument “männer” meegeef dan heb ik een heel vreemd verschijnsel. Wanneer ik dan op built en go klik en heb geen break points aan staan is mijn output anders dan wanneer ik een breakpoint op regel 8 (strncpy) zet en vervolgens een seconde wacht en dan op continue klik. Heeft hier iemand een verklaring voor waarom de arguments die binnen komen verschillend zijn wanneer ik break point wel of niet gebruik?

    De for loop geeft weer wat de verschillen zijn in het uitvoeren met en zonder breakpoint.

    <br />
    #include <iostream><br />
    #include <string><br />
    using namespace std;<br />
    int main (int argc, char * const argv[]) {<br />
    	char * a1;<br />
    	a1 = (char *) malloc(strlen(argv[1]) + 1);<br />
    	strncpy(a1, argv[1], strlen(argv[1]));<br />
    	for (int i = 0; i<strlen(a1);i++){<br />
    		cout << "a1: ";<br />
    		cout << i << " ";<br />
    		cout << " " << static_cast<unsigned int>(static_cast<unsigned char>(a1[i])) ;<br />
    		cout << " " << (static_cast<unsigned char>(a1[i])) << endl ;<br />
    	}<br />
    }<br />
     

    p.s. sorry voor onduidelijke code maar blijkbaar heeft OMT nog niet de code tag veranderd:(

    Bijdrager
    Ezri Dax

    Vreemd hij maakt van een ä een õ.

    Bijdrager
    dj bazzie wazzie

    Is het bij jou dan ook wanneer je een breakpoint op regel 8 (strncpy) zet dat hij dan wel ä blijft? Of is bij jou in beide gevallen een õ.

    Bijdrager
    Pieterr

    Door de strncpy wordt er geen terminating zero achter de a1 string gezet. De strlen(a1) kan dus van alles teruggeven.
    Je zou bv ipv een malloc een calloc kunnen gebruiken:

    a1 = (char *) calloc(strlen(argv[1]) + 1, sizeof(char));

    Maar eigenlijk zijn zowel malloc als calloc meer C constructies. In C++ gebruik je ‘new’.

    Bijdrager
    dj bazzie wazzie

    Is geen van beide het probleem helaas.

    ik heb geprobeerd met bzero eerst alle bytes op ” te zetten waardoor ik zeker weet dat strncpy goed lukt. Ook had ik voor dat ik gebruik maakte van malloc a1 = new char [strlen(argv[1]) +1] maar ook dit maakte niets uit. vandaar dat ik probeer helemaal terug te gaan naar standaard C met mijn code om op die manier proberen op te sporen in welke C++ class ik de fout maakte.

    Bijdrager
    Pieterr

    Door de ‘ä’ zit je ook nog met UTF8/Unicode geneuzel. Ik heb je programma net getest onder Windows. Zal straks thuis eens op de Mac kijken.

    Bijdrager
    dj bazzie wazzie

    even een paar kleine extra tests erbij:

    Wanneer ik de code kopieer en in snow leopard build is alles goed.

    Daarna wanneer ik de code helemaal basic maak (direct vanuit argv uitspuug) blijf ik hetzelfde probleem houden.

    int main (int argc, char * const argv[]) {
    for (int i = 0; i<strlen(argv[1]);i++){
    cout << “a1: “;
    cout << i << ” “;
    cout << ” ” << static_cast<unsigned int>(static_cast<unsigned char>(argv[1])) ;
    cout << ” ” << (static_cast<unsigned char>(argv[1])) << endl ;
    }
    }

    Volgens mij mag UTF-8 niet het probleem zijn. Mijn ä bestaat gewoon uit twee bytes wat betekend dat mijn for loop gewoon twee gatallen zou moeten returnen voor de ä.

    Dit is wat ik krijg (fout) zonder break point aan te hebben staan:

    <br />
    a1: 0  109 m<br />
    a1: 1  97 a<br />
    a1: 2  204 \314<br />
    a1: 3  136 \210<br />
    a1: 4  110 n<br />
    a1: 5  110 n<br />
    a1: 6  101 e<br />
    a1: 7  114 r<br />
     

    En dit is wat ik krijg (correct) wanneer ik wel break point aan zet op een willekeurige plek in de code.

    <br />
    a1: 0  109 m<br />
    a1: 1  195 \303<br />
    a1: 2  164 \244<br />
    a1: 3  110 n<br />
    a1: 4  110 n<br />
    a1: 5  101 e<br />
    a1: 6  114 r<br />
     

    Of nou een breakpount aan heb staan of niet naar mijn idee (en onder Snow Leopard) zou ik twee keer hetzelfde resultaat moeten krijgen. Mijn vraag is daarom hoe kan het dat het onder Leopard niet zo is.

    Bijdrager
    Ezri Dax

    a1: 0 109 m
    a1: 1 97 a
    a1: 2 204 \314
    a1: 3 136 \210
    a1: 4 110 n
    a1: 5 110 n
    a1: 6 101 e
    a1: 7 114 r

    met break op 8

    a1: 0 109 m
    a1: 1 195 \303
    a1: 2 164 \244
    a1: 3 110 n
    a1: 4 110 n
    a1: 5 101 e
    a1: 6 114 r

    dit krijg ik als ik hem helemaal handmatig doorstap:

    a1: 0 109 m
    a1: 1 195 \303\303a1: 2 164 \244
    a1: 3 110 n
    a1: 4 110 n
    a1: 5 101 e
    a1: 6 114 r

    ben nog wat aan het testen.

    Bijdrager
    Verwijder

    werk je in XCode of doe je het zelf in de Terminal? in het geval van XCode lijkt het een bug in XCode. in de Terminal gestart werkt het bij mij met en zonder gdb zoals het zou moeten.
    mijn theorie: met een breakpoint wordt het programma gestart door gdb, die doet het goed. zonder breakpoint wordt het programma gestart door XCode, die doet iets mis met dat UTF-gedoe. in 10.6/nieuwere XCode is de bug is verholpen.

    Bijdrager
    Ezri Dax

    Ik krijg een BusError buiten XCode

    Bijdrager
    TGV

    Ik denk dat Willem gelijk heeft. Het werkt nu overal hetzelfde (ik heb gisteren XCode geupdated) en ik denk dat als je de moeite neemt om de inhoud van a1 te inspecteren met het memory-venster, je zult zien dat die tekens er staan en er dus ten onrechte door XCode in gezet zijn.

    Bijdrager
    Ezri Dax

    Maar dan zat die bug er al heel lang in, ik werk op de laatste versie, volgens mij op de ppc (leopard) en daar geeft hij deze fout ook.

    Bijdrager
    dj bazzie wazzie

    @willemien:Ik werk in Xcode. Maar als ik je dus goed begrijp is er een verschil wanneer ik build & run en heb een breakpoint actief staan of niet ook al is mijn configuratie debug in plaats van release? Dat wist ik dus niet. Ik dacht dat het dan altijd door gdb gaat. Wanneer ik mijn gebouwde project draai vanuit de terminal (tekst encoding op UTF-8) dan werkt het ook goed. Ik denk dat je gelijk hebt en dat het een bug is in Xcode en ben inmiddels nieuwere versie aan het installeren. Ik laat weten als het over is, ik gebruik nu namelijk 3.1.3 en had nog een 3.2.2 op de server hier staan.

    Ik hou jullie op de hoogte

    EDIT: Ik heb ook nog 3.1.4 staan 3.2.x is Snow Leopard Only.

    Bijdrager
    Verwijder

    ik dacht ook dat met en zonder breakpoints altijd via gdb werd gestart maar ik heb het uitgeprobeerd met een ander programma en in Activiteitenweergave is te zien dat zonder breakpoints XCode het bovenliggend proces is. weer wat geleerd.

    Bijdrager
    dj bazzie wazzie

    Xcode 3.1.4 heeft zelfde probleem en ik denk dat ik maar naar Snow Leopard moet verhuizen:( en moet testen onder Leopard.

    Het was mij ook nog nooit eerder opgevallen maar nu had ik een fout bij het uitvoeren en bij het debuggen van mijn echte applicatie ging alles goed. Dus dan kom je aan het puzzelen en blijkt er dus een ‘bug’ in Xcode te zitten.

    Ik ga nu zo maken dat mijn applicatie een stream kan openen dan heb ik in iedergeval iets om mee te debuggen

    Bijdrager
    Ezri Dax

    Het gekke is dat C++ compilers op bijvoorbeeld Windows (zowel de klassieke Visual C++ 4.0 als de Visual Studio 2010 versie en de tussenliggende versies) õ laten zien in plaats van ä.

    Bijdrager
    dj bazzie wazzie

    Dat komt denk ik omdat XCode een psuedo terminal gebruikt voor input en output en ik denk dat Windows een ander input output systeem heeft en niet UTF-8 is. Het is een gokje maar ik denk dat daar het verschil zit tussen de verschillende IDE’s. Maar onder Windows zal net zoals xcode 3.2.x (gcc 4.2) geen verschil zitten wanneer je een breakpoint aan hebt staan of uit het zal consequent steeds een õ zijn.

17 berichten aan het bekijken - 1 tot 17 (van in totaal 17)

Je moet ingelogd zijn om een reactie op dit onderwerp te kunnen geven.