2016-02-20 25 views
8

Ich wollte Elemente aus einer Zeichenfolge in eine andere Zeichenfolge übertragen und schrieb daher das folgende Programm. Anfangs dachte ich, dass die for-Schleife ausgeführt werden sollte, bis das NULL-Zeichen (einschließlich d. H.) Kopiert wurde. Aber in diesem Code endet die for-Schleife, wenn ein NULL-Zeichen gefunden wurde (d. H. Noch nicht kopiert wurde), aber es kann immer noch die Zeichenkette anzeigen, in die die Elemente kopiert wurden. Wie ist das möglich, wenn es überhaupt kein NULL-Zeichen gibt?Kopieren von Elementen von einem Zeichen-Array zu einem anderen

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    char temp[100], str[100]; 
    fgets(str, 100, stdin); 
    int i; 
    for(i = 0; str[i]!='\0'; i++) 
    { 
     temp[i] = str[i]; 
    } 
    puts(temp); 
    return 0; 
} 
+3

'NULL' ist ein Makro mit einer _null-Zeigerkonstante_. Dies ist hier irrelevant. Sie meinen das ASCII-Zeichen 'NUL' oder' nul' mit dem ganzzahligen Wert '0'. – Olaf

+0

Lesen Sie über 'strcpy'. –

+1

@Pete Becker Ich denke, das ist SEHR wahrscheinlich so etwas wie ein Hausaufgaben-/Tutorial-Problem (* d. H. * Beabsichtigt/entworfen, um die Probleme beim Kopieren von Zeichenfolgen zu erkennen **). Jemandem einfach zu sagen, dass er über "strcpy" lesen sollte, hilft nicht, dieses Verständnis zu fördern. – Tersosauros

Antwort

7

Die void puts(const char *) Funktion beruht auf size_t strlen(const char *) und Ausgabe dieser Funktion ist undefined, wenn es in dem übergebenen Argumente (siehe this answer) kein Nullabschluss ist. Also in Ihrem Fall die strlen innerhalb puts wahrscheinlich einen 0-Wert "neben" Ihr Array im Speicher gefunden, was zu einem ordnungsgemäßen Verhalten von puts, aber das muss nicht immer der Fall sein, da es nicht definiert ist.

3

Wenn Sie char temp[100] deklarieren, ohne es zu initialisieren, benötigt es nur nicht initialisierten Speicher. Diese Erinnerung kann alles sein. Zum Beispiel wird das folgende Programm schreiben, den anfänglichen Inhalt, dass, wie ganze Zahlen:

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    char temp[100]; 
    int i; 
    for(i = 0; i < 100 ; i++) 
    { 
     fprintf(stdout, "%d ", temp[i]); 
    } 
    return 0; 
} 

Diese Drucke konsequent unterschiedlichen Ausgang für mich, obwohl von einigen Duseln es dem Druck von Nullen hält. zB:

88 -70 43 81 -1 127 0 0 88 -70 43 81 -1 127 0 0 1 0 0 0 0 0 0 0 112 -70 43 81 -1 127 0 0 0 64 -108 14 1 0 0 0 72 50 -13 110 -1 127 0 0 -128 -70 43 81 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -70 43 81

88 90 72 88 -1 127 0 0 88 90 72 88 -1 127 0 0 1 0 0 0 0 0 0 0 112 90 72 88 -1 127 0 0 0 -96 119 7 1 0 0 0 72 18 72 105 -1 127 0 0 -128 90 72 88 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 90 72 88

88 -6 -79 87 -1 127 0 0 88 -6 -79 87 -1 127 0 0 1 0 0 0 0 0 0 0 112 -6 -79 87 -1 127 0 0 0 0 14 8 1 0 0 0 72 34 57 104 -1 127 0 0 -128 -6 -79 87 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -6 -79 87

Was ist höchstwahrscheinlich passiert ist, dass Ihre Nicht-nullterminierten String wird aufgrund der Tatsache versehentlich nullterminierte ist, dass temp[strlen(str)] ist durch einen Zufallsfehler, \0.

+1

Drucken dieser Variablen ist undefiniertes Verhalten –

+0

@Giorgi Wie so? AFAIK, es ist definiert, dass ich 100 Bytes bekomme, aber die Werte dieser Bytes sind nicht definiert. Sie sollten sicher zu drucken sein, aber es ist nie garantiert, was sie sind. – yaakov

+2

Nein, bitte lesen Sie den Begriff des undefinierten Verhaltens. Nicht initialisierte Variablen lesen ist UB. –

7

Hier ist die Ein- und Ausgabe auf meinem Computer:

0 
0 
絯忐` 

Process returned 0 (0x0) execution time : 1.863 s 
Press any key to continue. 

Siehe den Müll "絯 忐`"? Dies ist ein nicht definiertes Verhalten. Ihr Programm funktioniert gut, weil Sie (un) Glück sind.

Noch einmal, undefined Verhalten verdienen nicht viel Diskussion.

+3

Ich wollte +1, bis ich diese letzte Zeile gelesen habe: ** "** _ undefinierte Verhaltensweisen verdienen keine Diskussion ._ **" ** Während es wahr ist, war das OP "(un) glücklich" wie du Ich denke, ich versäume es zu diskutieren, ** undefiniertes Verhalten ** ist * nicht in der Lage, die Frage richtig zu beantworten *. – Tersosauros

+1

Alles und alles kann passieren, wenn undefinierte Verhaltensweisen stattfinden. Wie K & R weise betont: "Wenn Sie nicht wissen, wie sie auf verschiedenen Maschinen ausgeführt werden, kann diese Unschuld Ihnen helfen, Sie zu schützen." Daher denke ich, dass es besser ist, nicht definierte Verhaltensweisen zu diskutieren. –

Verwandte Themen