String kopieren?

starbright

Grünschnabel
Bin zu blöd einen String zu kopieren. Was mach ich falsch?
Hatte mir das ungefähr so gedacht:

abc.exe text1 text2

aber strcpy geht nicht!?


int main(int argc, char *argv[])
{
char *sFileName;
char *sFileOut;

printf("%i\ %s %s %s %s\n",argc, argv[0], argv[1], argv[2], argv[3]);

printf("%s\n",argv[1]);
strcpy(sFileOut,argv[1]);
strcpy(sFileName,argv[1]);
printf("%s\n",sFileName);
printf("%s\n",sFileOut);

}
 
Meinst Du sowas:

char *sFileName="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
char *sFileOut="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
printf("%s\n",sFileName);

strcpy(sFileName,"AAAAAAAAAAAAAAAAAAAAAA");
printf("%s\n",sFileName);


Das erste Print geht noch, beim zweiten mal nicht mehr!?

Damit bekomme ich lediglich zwei gleiche Strings, da nicht kopiert sondern referenziert wird.
sFileName = argv[1];
sFileOut = argv[1];
strcat(sFileOut,".pgm");
printf("%s\n",sFileName);
printf("%s\n",sFileOut);
 
Zuletzt bearbeitet:
So muß man init:

char sFileName[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

keine Ahnung was
char *sFileName="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
macht ....
 
keine Ahnung was
char *sFileName="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
macht ....
Dieser Ausdruck liefert einen Zeiger auf einen Speicherbereich im Programmsegment, der nicht verändert werden kann. Damit wird also eine Konstante erzeugt.

Für die Initialisierung brauchst du nicht unbedingt eine Zeichkette zuzuweisen. Es geht nur darum, Speicher zu reservieren:
Code:
char sFileName[50];
Gruß
MCoder
 
Wobei sich natürlich auch noch die Frage stellt, wie lange du den Speicher benötigst, und je nach dem kommt jener dann vom Heap oder die Sachen kommen vom Stack. Kleines Beispiel:
Code:
char* tmp;
{
       char a[50] = { 0 };
       tmp = a;
}
tmp[46] = 'a';

Hier wird dein Programm bei der Anweisung tmp[46] = 'a' vermutlich abstürzen. Dies ist ganz einfach zu erklären. Der Speicher, der für a reserviert wird, kommt vom Stack. Dieser Stack wird am Ende eines jeden Blocks wieder aufgeräumt und der reservierte Speicher wieder freigegeben für weitere Verwendung. tmp hat aber immernoch diese Adresse gespeichert und daher möchtest du mit tmp[46] = auf Speicher zugreifen, der dir unter Umständen nicht mehr gehört.

Die Lösung dazu sieht folgendermassen aus:
Code:
char* tmp;
{
     char* a = new char[50];
     tmp = a;
}
tmp[46] = 'a';
delete [] tmp;

Mit dem Schlüsselwort new wird der Speicher vom Heap genommen. Das ist Speicher, der dem Programm mehr oder weniger fix beim Start zugeteilt wird, von dem es Speicher reservieren kann. Wichtig ist hierbei, dass dieser so lange reserviert bleibt, bis du ihn explicit mit delete wieder freigibst. Daher ist es ganz wichtig, dass bei jedem new irgendwo ein delete kommt, welches den Speicher wieder freigibt. Sonst ist dein Speicher schneller belegt, als es dir lieb ist ;)
 
Code:
char* tmp;
{
       char a[50] = { 0 };
       tmp = a;
}
tmp[46] = 'a';

Hier wird dein Programm bei der Anweisung tmp[46] = 'a' vermutlich abstürzen. Dies ist ganz einfach zu erklären. Der Speicher, der für a reserviert wird, kommt vom Stack. Dieser Stack wird am Ende eines jeden Blocks wieder aufgeräumt
Ein Block (geschweifte Klammern) innerhalb einer Methode/Funktion begrenzt nur die Sichtbarkeit der darin erzeugten Variablen, Der von ihnen allozierte Speicher bleibt aber bis zum Ende der Methode/Funktion verfügbar. Daher wird der obige Code nicht abstürzen.

Gruß
MCoder
 
So muß man init:

char sFileName[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

keine Ahnung was
char *sFileName="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
macht ....

Das ist das komplett gleiche...
Mitnichten. Wie MCoder schon erklärt hat, wird mit der zweiten Methode eine Zeichenkettenkonstante referenziert. Versucht man eine solche zu modifizieren, kommt es zu einem Speicherzugriffsfehler (segfault). Dagegen ist die erste Methode die Initialisierung eines Arrays, das auf dem Stack angelegt wird.

Grüße, Matthias
 
Ein Block (geschweifte Klammern) innerhalb einer Methode/Funktion begrenzt nur die Sichtbarkeit der darin erzeugten Variablen, Der von ihnen allozierte Speicher bleibt aber bis zum Ende der Methode/Funktion verfügbar. Daher wird der obige Code nicht abstürzen.
Dazu hätte ich jetzt aber mal gerne den Auszug ausm Standard. Es wird wahrscheinlich nicht abstürzen weil niemand so schnell wieder auf den Speicher zugegriffen haben wird und was neues drin steht ... aber das ist nunmal undefiniert ;)

Hm das Programm am Anfang sah übrigens eher nach C aus und würde d.h. auch mit malloc arbeiten :D
C++:
int main(int argc, char *argv[])
{
    // Alle übergebenen Argumente ausgeben
    for (int i = 0; i < argc; ++i) 
        printf("%02i. %s\n", i, argv[i]);
	
    // Speicher zum Kopieren des Strings auf dem Heap anfordern
    char* sFileName = (char*)malloc(sizeof(char) * (strlen(argv[1]) + 1));
    // Inhalt von argv[1] in sFileName kopieren
    strcpy(sFileName, argv[1]);
    // Ausgabe des neuen Strings
    printf("%s\n",sFileName);
    // Speicher wieder freigeben (auf dem Heap geht's nicht automatisch)
    free(sFileName);
}
 
Zuletzt bearbeitet:
Zurück