-1
votes

Avoir du mal à concaténer le prénom et le nom de famille

Voici mon code:

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

int main(void)
{
    char firstName[10];
    char lastName[10];
    char fullName[30];
    int length, length2;
    printf("Please enter the first name: ");
    scanf("%s", firstName);
    length = strlen(firstName);
    while (length > 10)
    {
        printf("Error! First name should have < 10 characters.\n");
        printf("Please enter the first name again: ");
        scanf("%s", firstName);
        length = strlen(firstName);
    }
    printf("Please enter the last name: ");
    scanf("%s", lastName);
    length2 = strlen(lastName);
    while (length2 > 10)
    {
        printf("Error! Last name should have < 10 characters.\n");
        printf("Please enter the last name again: ");
        scanf("%s", lastName);
        length2 = strlen(lastName);
    }
    strcpy(fullName, firstName);
    strcat(fullName, " ");
    strcat(fullName, lastName);
    printf("The full name is: %s\n", fullName);
    return 0;
}

c

1 commentaires

scanf ("% 9s", prénom); - prénom ne peut jamais contenir plus de 9 + 1 caractères afin que tandis que (longueur> 10) est impossible sans comportement indéfini ... (la même chose s'applique à lastname ) alors quelle est la leçon? Ne lésinez jamais sur la taille de la mémoire tampon! et protégeez vos limites de la matrice au point de remplissage (pas après - il est trop tard alors).


3 Réponses :


0
votes

La logique pour moi semble bien mais il devrait y avoir si l'état au lieu de la boucle.


1 commentaires

Pourquoi devrait-il y avoir un si au lieu d'un pendant ?



1
votes

Strcpy () et strcat () ne sont pas de toute la longueur-sécurité. Il faut utiliser strncpy () et strncat () . Mais si le tampon n'est pas assez long, ces deux fonctions ne se terminent pas.

Une solution facile pour votre cas est d'utiliser snprintf () qui sera toujours null terminer: xxx


0 commentaires

0
votes

Chaque fois que vous utilisez des tableaux de taille fixe dans C, comme FULLNAME et lecture des informations dans la matrice, vous devez mettre votre chapeau de comptables et vous assurer que vous n'écrivez plus de caractères à la matrice que ce qu'il ne peut HOLD (moins 1 caractère du caractère Nul-terminade si vous souhaitez utiliser le tableau de caractères en tant que chaîne)

Comme mentionné dans mon premier commentaire, lors de l'utilisation du SCANF La famille, vous devez utiliser le modificateur largeur de champ pour vous assurer que scanf ne lit plus que Taille - 1 caractères conserver la place pour le caractère Nul-terminant . Sinon, scanf sera heureux d'écrire en dehors des limites de votre matrice invoquant comportement non défini (signification définie l'exécution de votre code est terminée à ce stade et que votre code pourrait sembler fonctionner normalement ou segfault - ou quoi que ce soit entre les deux)

qui soulève le meilleur conseil que quiconque peut donner - ne tentez pas de lire des lignes d'entrée utilisateur avec scanf . Utilisez plutôt fgets (ou posix getline ) pour lire une ligne entière à la fois, puis analyser tout ce dont vous avez besoin de la ligne (ou si vous utilisez toute la ligne en tant que chaîne, Il suffit de couper le '\ n' à partir de la fin). De cette façon, ce qui reste dans votre mémoire tampon d'entrée ne dépend pas du spécificateur de conversion utilisé (qui tourmente les nouveaux C programmeurs de C ...) < P> Lors de la prise d'entrée de l'utilisateur, vous devez toujours protéger contre l'entrée d'annulation de l'utilisateur en entrant Ctrl + D (ou Ctrl + Z sous Windows) pour générer un manuel Eof . Vous faites cela en vérifiant le retour de la fonction d'entrée que vous utilisez.

Si vous souhaitez vous assurer que l'utilisateur vous donne une entrée (ou des annuels) valide, il suffit de placer votre invite et de lire dans une boucle continue et pause; la boucle une fois que l'entrée a satisfait toutes vos conditions.

Lorsque vous lisez plus d'une entrée dans le même tampon comme FullName , il aide à Gardez une variable contenant le disponible (ou restant ). De cette façon au lieu de tester la taille de la mémoire tampon complète pour votre deuxième entrée, vous testez les caractères restants disponibles dans le tampon pour voir si votre lastname sera adapté (plus un caractère supplémentaire pour le " " (espace) entre le premier / nom Nom.

Pour vous assurer que l'entrée s'adaptera, lisez-le dans un tampon temporaire de taille suffisante (* Ne lésinez pas la taille de la mémoire tampon!), par exemple xxx

ci-dessus, vous avez un tampon temporaire de 1024 caractères - qui devrait être plus que suffisant à moins que le chat de l'utilisateur se dorme sur le clavier . Vous allez lire dans le tampon 1024 et puis testez si cela s'adaptera dans les caractères disponibles pour FULLNAME . Combinoir qui sera une lecture continue boucle que vous pourriez faire: xxx

( note: Il n'y a pas besoin de prénom ou lastname comme vous mettez à la fois en FullName . Il suffit de lire avec buf et d'ajouter à FULLNAME Comme vous allez)

Notez également l'utilisation de strcspn qui renvoie le nombre de caractères de la chaîne non contenue dans l'ensemble exclude "\ r \ n" . Donc, il lit le nombre de caractères dans la chaîne jusqu'à la première fin de ligne rencontrée - an écrase la ligne terminant avec zéro (identique que '\ 0' ) sur Nul-terminer à ce point . Vous pouvez utiliser strallen , mais strcspn peut le faire pour vous incorporer l'ensemble excluant vous permettant de terminer Nul-terminer dans une seule commande.

La lecture du nom de famille est presque identique au prénom, sauf lorsque vous allez ajouter un nom de famille à FullName Vous devez ajouter un "" avant de faire. La différence étant: xxx

la mettant tout à fait, vous pourriez faire: xxx

Exemple d'exemple Utilisez / sortie < / strong> xxx

ou le cas où l'utilisateur annule l'entrée: xxx

regarde les choses et laissez-moi savoir si Vous avez d'autres questions.


0 commentaires