Dit is een topic in Community » Forum » Pro » Software-ontwikkeling

[C/C++]Command Line Arguments

dj bazzie wazzie

dj bazzie wazzie op 24 augustus 2010 #

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

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

MadDonna

MadDonna op 24 augustus 2010 #

Vreemd hij maakt van een ä een õ.

dj bazzie wazzie

dj bazzie wazzie op 24 augustus 2010 #

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 õ.

Pieterr op 24 augustus 2010 #

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'.

dj bazzie wazzie

dj bazzie wazzie op 24 augustus 2010 #

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.

Pieterr op 24 augustus 2010 #

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.

dj bazzie wazzie

dj bazzie wazzie op 24 augustus 2010 #

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][i])) ;
cout << " " << (static_cast<unsigned char>(argv[1][i])) << 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:

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

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

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

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.

MadDonna

MadDonna op 24 augustus 2010 #

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 303303a1: 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.

Willemien op 25 augustus 2010 #

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.

MadDonna

MadDonna op 25 augustus 2010 #

Ik krijg een BusError buiten XCode

TGV

TGV op 25 augustus 2010 #

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.

MadDonna

MadDonna op 25 augustus 2010 #

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.

dj bazzie wazzie

dj bazzie wazzie op 25 augustus 2010 #

@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.

Willemien op 25 augustus 2010 #

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.

dj bazzie wazzie

dj bazzie wazzie op 25 augustus 2010 #

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

MadDonna

MadDonna op 25 augustus 2010 #

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 ä.

dj bazzie wazzie

dj bazzie wazzie op 26 augustus 2010 #

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.

Je kunt alleen reageren met een gratis OMT account.
Log in of registreer.

Inloggen

Over dit topic

Gestart op 24 augustus 2010 door dj bazzie wazzie

Laatste reactie door dj bazzie wazzie

Reageer op dit topic