1
votes

Sortie inattendue lors de la tentative d'impression de l'entrée utilisateur via des tableaux

Ce code prend l'entrée utilisateur dans un tableau et l'affiche ensuite. Chaque fois que j'imprime l'entrée utilisateur, un caractère supplémentaire aléatoire est imprimé à la fin.

Enter a sentence:abc

Par exemple, je m'attendais à la sortie de

#include <stdio.h>
#include <ctype.h>

int main(void) 
{
    char arr[100]; 
    char c;
    printf("Enter a Sentence:");
    int i =0;
    for (i = 0;(c = getchar()) != '\n';++i)
        arr[i] = c;
    arr[++i] = '\n';
    for (int i = 0;arr[i] != '\n';++i)
        putchar(arr[i]);
}

être abc mais à la place j'ai eu abcu.

c

5 commentaires

Inutile d'inclure: #include .


1) le code affiché n'a pas de limite sur le nombre de caractères que l'utilisateur peut saisir. Ceci est une erreur potentielle. 2) le code publié ne parvient pas à afficher le '\ n' final, de sorte que les données ne seront pas réellement sorties avant la fin du programme


Vous devez utiliser le type int pour c , et non le type char . C'est le type renvoyé par getchar , et vous ne pourrez pas distinguer correctement une valeur EOF si vous transtypez le résultat en char avant de vérifier il.


Ceci est un autre exemple de la raison pour laquelle l'opérateur préincrément (par exemple ++ i ) doit être évité en faveur de l'opérateur postincrement i ++ < / code>.


Ce code ne doit pas être compilé. Vous définissez i deux fois: int i = 0; et for (int i = 0; arr [i]! = '\ N'; ++ i) .


4 Réponses :


0
votes

Lorsque vous lisez la nouvelle ligne, i vient d'être augmenté à 3 par l'expression de mise à jour dans la première boucle for .

Ensuite, arr [++ i] = '\ n' augmente i à 4 et affecte à arr [4] . Rien n'est jamais attribué à arr [3] , mais il semble que cet emplacement contenait un u lorsque le tableau a été alloué à partir de la pile.


0 commentaires

1
votes

Ceci :

char arr[100] = { '\0' };

devrait être ceci:

for (i = 0;(c = getchar()) != '\n' && i < 100;++i)
    arr[i] = c;
arr[i] = '\n'; /* here */

Vous sautez un caractère du tampon, comme i avait déjà été incrémenté à la fin de la boucle précédente. Cela lit les données non initialisées du tampon (probablement provenant de la pile).

Vous ne vous arrêtez pas non plus au-delà de la fin du tampon, ce qui pourrait provoquer un débordement de tampon.

Avec cela, vous devriez probablement initialiser le tableau avec ceci:

for (i = 0;(c = getchar()) != '\n';++i)
    arr[i] = c;
arr[++i] = '\n'; /* here */


0 commentaires

3
votes

Remplacez ce

for (i = 0; i < sizeof(arr)-1 && (c = getchar()) != '\n';++i) {
     arr[i] = c;
}

par

char arr[100] = {}; /* zerod whole array */

car la variable i est déjà incrémentée dans la partie condition de for boucle ici

for (i = 0;(c = getchar()) != '\n';++i /* before loop terminating i incremented here */) {
     arr[i] = c;
 }

Il est également bon d'initialiser le tampon tout en se déclarant pour éviter d'obtenir une valeur indésirable. Par exemple,

arr[i] = '\n';

Et assurez-vous également que cela (c = getchar ())! = '\ N' ne se produit pas > 100 fois sinon un dépassement de tampon se produit, ce qui entraîne un comportement indéfini . Une manière possible est

arr[++i] = '\n'; /* this skips the current a[i] & put \n into next position which is incorrect */


0 commentaires

1
votes

Concernant:

arr[i] = '\n';

Ceci incrémente i avant d'attribuer '\ n' , donc arr [++ i ] pointe un caractère supplémentaire dans le tableau.

C'est pourquoi un caractère inattendu est imprimé.

Si vous remplacez cette instruction par:

arr[++i] = '\n';

votre code devrait fonctionner.


3 commentaires

@ JL2210, Il existe de nombreuses façons de corriger le code. Tellement demander que l'OP corrige le code d'une certaine manière, comme le fait votre modification, est très trompeur. C'est pourquoi ma réponse (originale) 'suggérait' plutôt qu'exigeait un correctif spécifique


Est-ce mieux?


@ JL2210: Oui, c'est bien mieux