2017-12-29 20 views
0

Ich benutze ein Array in diesem Code, weil ich eine Zeichenfolge brauche, die immer geändert werden sollte, deshalb verwende ich keinen Zeiger, wie immer, wenn ich den Code ausführe, bekomme ich ein seltsames Verhalten bei die 31. Iteration.Zufälliges Zeichen merkwürdig definiertes Verhalten

Code

int i = 0; 
char name[100]; 
srand(getpid()); 


while(i<100) { 

    name[i] += (char)'A'+(rand()%26); 
    printf("%d strlen\n", i+1); 
    printf("%s\n", name); 
    printf("/////\n"); 
    i++;  
} 

Ausgang

///// 
30 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOY 
///// 
31 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJ 
///// 
32 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJWttime 
///// 
33 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW�time 
///// 
34 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW��ime 
///// 
35 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW���me 
///// 
36 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW����e 
///// 
37 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW����� 

Mit anderen Worten: es druckt immer ttime als der 31. Charakter und überschreibt dann den Code jedes Zeichen des Wortes und i Fragezeichen als Ergebnis.

auf die Dinge gehen noch schlimmer Blick auf die endgültige Ausgabe

100 strlen 
IKXVKZOLKHLTKBFFTUZCYXHYVEBZOYJW�����K��ȶ������MKRLHALEV�SNNRVWNOEXUVQNJUHAEWN�W�YPMCW�N�PXHNT��0� 
///// 

Warum passiert das das?

+0

'name' ist nicht '0' out, bevor das Spiel beginnt, wird dann als C-String behandelt: Das berüchtigte undefinierte Verhalten schlägt erneut zu. – alk

+0

Ich wette, Sie haben bereits Erfahrung mit anderen Sprachen. C-Saiten sind komisch - aber vorhersehbar. 'string + = 'x'' macht nicht, was du denkst. – usr2564301

+0

@alk was meinst du damit ist nicht 0-out bevor das Spiel startet? –

Antwort

1

Nun, Sie drucken Müll Wert. Was das Verhalten sein wird, ist nicht bekannt. (Undefiniertes Verhalten) Damit meine ich, dass diese Müllwerte (die mit Ihrer Zufallszahl addiert werden) Ascii-Werte einiger Zeichen sein können oder dass es sich um einige Nicht-Ausdrucke handelt . Sie sollten den char-Array (mit \0 ‚s - das wird erfüllt zwei Zwecke, \0 für den Laufstrang Bereitstellung und auch können Sie hinzufügen und sicher sein, es eine druckbare sein wird) initialisiert oder es nur zuweisen.

name[i] = 'A'+(rand()%26); 

setzen sich auch ein \0 am Ende des Strings. Andernfalls wird versucht, auf den Array-Index zuzugreifen, bis er \0 findet und unbestimmtes Verhalten auslöst.

31 ist nicht etwas Besonderes - es ist alles schon am nächsten Mal, wenn Sie es ausgeführt werden kann.

Code:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main(void) { 
    size_t i = 0; 
    char name[100]={0}; // = ""; 
    srand(getpid()); 

    while(i<99) { // till 99 making sure you won't overwrite the last NUL 

     name[i] ='A'+(rand()%26); 
     printf("%d strlen\n", i+1); 
     printf("%s\n", name); 
     printf("/////\n"); 
     i++;  
    } 
    return 0; 
} 

Bitte beachte, dass wir bis 98 th Index geschlungen haben, weil es NUL beendet Zeichen im 99 ten Index ist.

1

char name[100]; ist standardmäßig kein String. Es ist nur ein weiteres 100 Element char Array.

In C Ein String ist eine immer Tragen (mindestens) ein '\0' Zeichen das Ende der Schnur zu markieren. printf(), meist alle str*() Funktionen und viele andere Funktionen verlassen sich auf diesen Abschluss '\0'.

Auch was ist die Idee hinter dem Hinzufügen zu den Array-Elementen?

name[i] += ... 

Ihre Werte sind nicht festgelegt, sie sind Müll. Sogar wert, wenn man sie hinzufügt, bedeutet das Lesen von nicht initialisiertem Speicher 1st, was wiederum undefiniertes Verhalten provoziert.

So Ihr Code zu beheben den Terminator von Hand der Zusatz hinzufügen fallen:

while (i < 99) { 
    name[i] = (char) 'A' + (rand() % 26); 
    name[i + 1] = '\0'; 

Oder gehen Sie für den faulen Ansatz jede Initialisierung name allen '\0' noch vor dem Start:

char name[100] = ""; /* or ... = {0}; */ 

(diese würde es Ihnen ermöglichen, dabei zu bleiben name[i] += ....Noch, da alle Elemente sind 0, ist die Zugabe keine Verwendung.)

In beliebig Fall Schleife nicht bis zum Array letzten Element (100 hier), aber immer eine weniger als das letzte Element ist für den Abschluss '\0' reserviert.

+0

danke du bist lösung es ist richtig, ich habe die andere gewählt, nur weil er vorher geantwortet hat –

0

Wenn das Array char name[100] eine lokale Variable innerhalb einer Funktion ist, ist der Anfangswert nicht definiert. So wird es enthalten, was auch immer zufälliger Müll in diesem Stück Speicher war.

Deshalb, wenn Sie tun

name[i] += (char)'A'+(rand()%26); 

Sie tatsächlich tun,

name[i] = RANDOM JUNK + (char)'A'+(rand()%26); 
Verwandte Themen