2 votes

Un tableau unidimensionnel mais plusieurs chaînes

Je veux créer une chaîne de caractères multiple avec un tableau unidimensionnel, est-ce possible?

#include 

int main()
{
    char name1[10];
    char name2[10];

    printf("Entrez le nom1: ");
    scanf("%s", name1);

    printf("Entrez le nom2: ");
    scanf("%s", name2);

    printf("\n%s", name1);
    printf("\n%s", name2);

    return 0;
}

Je viens de commencer à apprendre les tableaux et je voulais essayer d'obtenir plusieurs entrées de l'utilisateur et d'afficher uniquement certains éléments. C'est l'un des codes que j'ai essayés avant mais ça ne fonctionne pas.

int main()
{
    char *name[10];

    int i = 1, input;
    printf("Combien de jours par semaine: "); 
    scanf("%d", &input);

    do{
        printf("entrer le jour %d: ", i);
        scanf("%s", name[i]);
        i++;
    }while(i < input);

    //Résultat souhaité
    printf("\n%s", name[0]);
    printf("\n%s", name[4]);

    return 0;
}

2voto

Refugnic Eternium Points 2773

Une demande plutôt particulière, mais elle pourrait être réalisée ainsi :

#include 

int main()
{
    char names[256];

    printf("Enter name1: ");
    scanf("%s", names);

    printf("Enter name2: ");
    scanf("%s", names + strlen(names) + 1);

    printf("\n%s", names);
    printf("\n%s", names + strlen(names) + 1);

    return 0;
}

De cette manière, les chaînes de caractères sont concaténées dans le tableau et séparées par le 0 de terminaison.

2voto

Andreas Wenzel Points 5088

Votre question est très vague, mais il me semble que vous ne voulez pas un tableau à une dimension, mais plutôt un tableau à deux dimensions (malgré le fait que votre question affirme explicitement le contraire).

Je suggère de changer char *name[10]; en char name[10][10]; De plus, vous voudrez peut-être changer le nom de la variable du tableau 2D name en names, car ce nom est trompeur, car il implique qu'il ne contient qu'une seule chaîne.

De plus, vous devez commencer le compteur de boucle i à 0, pas à 1, car les index de tableau sont basés sur zéro en C.

Après avoir apporté ces modifications, votre programme devrait ressembler à ceci:

#include 

int main( void )
{
    char names[10][10];

    int i = 0, input;
    printf("Combien de jours par semaine: "); 
    scanf("%d", &input);

    do{
        printf("Entrez le jour %d: ", i+1);
        scanf("%s", names[i]);
        i++;
    }while(i < input);

    //sortie souhaitée
    printf("Le premier jour est: %s\n", names[0]);
    printf("Le cinquième jour est: %s\n", names[4]);

    return 0;
}

Ce programme a le comportement suivant:

Combien de jours par semaine: 7
Entrez le jour 1: Lundi
Entrez le jour 2: Mardi
Entrez le jour 3: Mercredi
Entrez le jour 4: Jeudi
Entrez le jour 5: Vendredi
Entrez le jour 6: Samedi
Entrez le jour 7: Dimanche
Le premier jour est: Lundi
Le cinquième jour est: Vendredi

Remarquez que le programme écrira dans le tableau en dehors des limites si l'utilisateur entre un entier plus grand que 10 ou si l'un des jours a une longueur supérieure à 9 (10 en incluant le caractère nul de terminaison).

De plus, votre programme aurait une structure plus propre si vous utilisiez une boucle for au lieu d'une boucle while, car cela réduit la portée du compteur de boucle.

Un autre problème est que le programme se comportera mal si l'utilisateur n'entre pas un nombre. Au lieu de cela, il devrait vérifier si la fonction scanf a réussi, et afficher un message d'erreur s'il n'a pas réussi.

Par conséquent, il serait préférable de l'écrire de la manière suivante:

#include 
#include 

#define MAX_DAYS 10

//MAX_DAY_LENGTH_FORMAT_STRING, qui est utilisé par scanf,
//doit toujours être défini à un de moins que MAX_DAY_LENGTH,
//car ce dernier a également besoin de place pour le caractère nul de terminaison
#define MAX_DAY_LENGTH 10
#define MAX_DAY_LENGTH_FORMAT_STRING "%9s"

int main( void )
{
    char names[MAX_DAYS][MAX_DAY_LENGTH];
    int num_days;

    //demander à l'utilisateur une saisie
    printf( "Combien de jours par semaine: " );

    //essayer de lire l'entrée
    if ( scanf( "%d", &num_days ) != 1 )
    {
        printf( "Erreur de saisie!\n" );
        exit( EXIT_FAILURE );
    }

    //vérifier que l'entrée est dans la plage souhaitée
    if ( ! ( 1 <= num_days && num_days <= 10 ) )
    {
        printf( "Entrée hors de portée!\n" );
        exit( EXIT_FAILURE );
    }

    for ( int i = 0; i < num_days; i++ )
    {
        int num_lu;

        //demander à l'utilisateur une saisie
        printf( "Entrez le jour %d: ", i+1 );

        //essayer de lire l'entrée
        if ( scanf( MAX_DAY_LENGTH_FORMAT_STRING "%n", names[i], &num_lu ) != 1 )
        {
            printf( "erreur de saisie!" );
            exit( EXIT_FAILURE );
        }

        //vérifier si l'entrée était assez petite pour tenir dans le tampon
        if ( num_lu == MAX_DAY_LENGTH && getchar() != '\n' )
        {
            printf( "Entrée trop longue pour tenir dans le tampon!\n" );
            exit( EXIT_FAILURE );
        }
    }

    //imprimer la saisie à l'utilisateur
    printf("Le premier jour est: %s\n", names[0]);
    printf("Le cinquième jour est: %s\n", names[4]);

    return EXIT_SUCCESS;
}

Le programme effectuera désormais une validation appropriée de l'entrée au lieu de causer un comportement indéfini en cas d'entrée erronée:

Combien de jours par semaine: abc
Erreur de saisie!

Combien de jours par semaine: 11
Entrée hors de portée!

Combien de jours par semaine: 7
Entrez le jour 1: Lundi
Entrez le jour 2: Mardi
Entrez le jour 3: Mercredi
Entrez le jour 4: Jeudi
Entrez le jour 5: Vendredi
Entrez le jour 6: Samedi
Entrez le jour 7: Dimanche
Le premier jour est: Lundi
Le cinquième jour est: Vendredi

1voto

chqrlie Points 17105

La raison pour laquelle votre code ne fonctionne pas est que le tableau de pointeurs char *name[10]; n'est pas initialisé, donc vous passez une adresse invalide name[i] à scanf().

Vous pouvez initialiser le tableau de manière explicite de cette manière :

#include 

int main() {
    char name0[20], name1[20], name2[20], name3[20], name4[20];
    char name5[20], name6[20], name7[20], name8[20], name9[20];
    char *name[10] = { name0, name1, name2, name3, name4,
                       name5, name6, name7, name8, name9 };
    int i, input;
    printf("Combien de jours par semaine : "); 
    if (scanf("%d", &input) != 1 || input < 1 || input > 10) {
        fprintf(stderr, "entrée invalide\n");
        return 1;
    }

    for (i = 0; i < input; i++) {
        printf("entrer jour %d : ", i + 1);
        if (scanf("%19s", name[i]) != 1) {
            fprintf(stderr, "entrée invalide\n");
            return 1;
        }
    }

    //résultat souhaité
    printf("%s\n", name[0]);
    if (input > 4)
        printf("%s\n", name[4]);

    return 0;
}

En alternatif, vous pouvez utiliser un tableau 2D :

#include 

int main() {
    char name[10][20];
    int i, input;
    printf("Combien de jours par semaine : "); 
    if (scanf("%d", &input) != 1 || input < 1 || input > 10) {
        fprintf(stderr, "entrée invalide\n");
        return 1;
    }

    for (i = 0; i < input; i++) {
        printf("entrer jour %d : ", i + 1);
        if (scanf("%19s", name[i]) != 1) {
            fprintf(stderr, "entrée invalide\n");
            return 1;
        }
    }

    //résultat souhaité
    printf("%s\n", name[0]);
    if (input > 4)
        printf("%s\n", name[4]);

    return 0;
}

0voto

Lundin Points 21616

Consultez cette FAQ sur la manipulation des chaînes de caractères pour débutants : Pièges courants de la manipulation des chaînes de caractères en programmation C. La vôtre est la FAQ n°3 - vous essayez de stocker des données en utilisant un pointeur qui ne pointe pas vers un emplacement mémoire valide.

char *name[10]; est correct dans la mesure où il peut être utilisé pour la syntaxe name[i] afin d'accéder à une chaîne de caractères. Cependant, il s'agit simplement d'un tableau de pointeurs qui ne pointent pas encore vers des données allouées. Vous devez définir ces pointeurs pour qu'ils pointent quelque part avant de les utiliser.

Une façon de le faire :

char name1[100];
char name2[100];
char* name[10] = {name1, name2};
...
scanf("%s", name[i]); // maintenant c'est bon

Alternativement en utilisant l'allocation dynamique :

#include 
...

char* name[10];
for(int i=0; i<10; i++)
{
  name[i] = malloc(100);
  if(name[i]==NULL) { /* gérer l'erreur */ return 0; }
}
...
scanf("%s", name[i]); // maintenant c'est bon
...
for(int i=0; i<10; i++) // nettoyage
{
  free(name[i]);
}

L'avantage de l'allocation dynamique est que nous pouvons realloc une chaîne plus tard pendant l'exécution pour modifier la longueur de la chaîne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X