IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

questions sur les chaînes de caractères/strcat


Sujet :

C

  1. #1
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut questions sur les chaînes de caractères/strcat
    Bonjour,
    j'ai des questions sur les chaines de caractères (malgré que je viens de lire des pdf sur les chaines de caractères mais je n'ai pas trouvé des réponses à mes questions),
    1. le blanc n'est pas considéré comme un caractère ?
      j'ai fais ce code:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      	char ch1[50],ch2[50],ch5[50]; 
      	scanf("%s",ch1);
      	scanf("%s",ch2);
      et quand je veux saisir dans ch1: par example "bonjour sara"
      il stocke "bonjour" dans ch1 et "sara" dans ch2, il considère le blanc(l'espace) comme un retour ? Donc le blanc n'est pas un caractère ?
      N'est-il pas possible d’écrire une chaîne de caractère avec un espace ?
    2. y-a-t'il & dans le scanf pour saisir une chaine de caractère ?
      dans le scanf je met l'adresse & ou pas ? J'ai trouvé les deux ecriture scanf("%s,&ch); et scanf("%s",ch); quelle est l’écriture correcte ?
    3. strcat ?
      comment mettre la concaténation de deux chaine 1 et 2 dans une nouvel chaine par exemple chaine3 ?
      voici ce que j'ai fais:
      chaine3=strcat(chaine1,chaine3); mais cette fonction n'admet pas un paramètre de sortie je crois et j'ai remarqué qu'elle met le résultat dans chaine1, comment je peux la mettre dans chaine3, et ne pas changer le contenu de chaine1 ?


    Merci beaucoup

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 752
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    3.strcat ?
    comment mettre la concaténation de deux chaine 1 et 2 dans une nouvel chaine par exemple chaine3?
    voici ce que j'ai fais:
    chaine3=strcat(chaine1,chaine3); mais cette fonction n'admet pas un paramètre de sortie je crois et j'ai remarqué quel met le résultat dans chaine1, comment je peux la mettre dans chaine3, et ne pas changer le contenu de chaine1?
    Trivial

    (PS: je n'ai pas regardé la signature de strcat et je te fais confiance sur le traitement "in place" de strcat)
    1. Un malloc pour allouer ch3 : strlen(ch1) + strlen(ch2) + 1 (le fameux caractère '\0');
    2. Un strcpy pour copier ch1 dans ch3
    3. Un strcat pour concaténer ch2 dans ch3 après ch1. À vérifier si strcat recherche le caractère '\0' pour trouver la fin de ch1
    4. On ajoute le caractère final '\0'
    5. Et à la toute fin on supprime ch3 (avec free)

  3. #3
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 759
    Par défaut
    Hello,

    1) si, le blanc est considéré comme un caractère, ton problème de lecture de "bonjour sara" vient de la manière de fonctionner de scanf(). Voir ici un tutoriel sur la fonction scanf()
    2) scanf() attend un pointeur sur une adresse mémoire où seront stockées les données lues / interprétées; dans ce que tu montres, ch est déjà uin pointeur, donc pas besoin d'utiliser &
    3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    strcpy(ch3,ch1);
    strcat(ch3,ch2);
    A+

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Quelques remarques importantes afin de compléter les réponses de mes vdd :

    1. Une chaîne de caractères en C est une séquence d'octets terminée par un octet supplémentaire de valeur '\0' (caractère nul), et rien d'autre. Il n'y a aucun moyen de déterminer si une séquence d'octets est une chaîne C sans la parcourir.
    2. scanf n'est pas le bon outil pour lire une chaîne de caractères qui contient des caractères d'espacement, il faut utiliser fgets pour ce faire.


    Une conséquence du premier point est que la différence fondamentale entre les familles mem* et str* est que la première est conçue pour opérer sur des séquences d'octets de valeurs arbitraires alors que les fonctions de la seconde recherchent toujours le caractère de fin de chaîne (contrainte supplémentaire).

    @foetus : c'est l'exemple classique en effet mais techniquement, à partir du moment où tu fais un strlen sur une chaîne, tu ne devrais plus avoir à invoquer aucun str*. Alternativement, on peut utiliser des extensions non standard comme stpcpy.

  5. #5
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut
    merci beaucoup pour vos reponses
    voici le code que j'ai fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	char ch1[50],ch2[50],ch3[50];
     
    	// Saisir trois chaînes de caractères Ch1,Ch2 et Ch3:
    	gets(ch1);	
    gets(ch2);	
    gets(ch3);	
        // Mettre dans  Ch3 la concaténation de Ch1 et Ch2.
       strcpy(ch3,ch1);
       strcat(ch3,ch2);
       printf("la chaine 3:\n");
       puts(ch3);
    normalement j'ai bien comprais la difference entre scanf et gets: la premiere pour saisir un mot attaché(sans espace), et gets pour saisir une phrase mm avec espace.
    ***************************************
    voici une explication interessnte:
    Le comportement de gets diffère de scanf avec un %s sur les points suivants :
    - Pour gets, seule la fin de ligne sert de délimiteur alors que pour %s, il existe 5 caractères délimiteurs qu’on nomme des espaces blancs ; la chaine lue par gets peut donc contenir n’importe quel caractère espace blanc (excepté \n), en particulier des espaces.
    - Ce caractère fin de ligne est consommé par la lecture, c’est-à-dire que le pointeur ne reste pas placé dessus comme il le ferait avec le code %s dans scanf. Cela signifie qu’une prochaine lecture, en particulier par gets, accédera bien au caractère de la ligne suivante.
    ***************************************

  6. #6
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Quelques remarques importantes afin de compléter les réponses de mes vdd :

    1. [b]
    2. scanf n'est pas le bon outil pour lire une chaîne de caractères qui contient des caractères d'espacement, il faut utiliser fgets pour ce faire.
    j'ai utilisé gets au lieu de fgets! quel est la différence?

  7. #7
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    2) scanf() attend un pointeur sur une adresse mémoire où seront stockées les données lues / interprétées; dans ce que tu montres, ch est déjà uin pointeur, donc pas besoin d'utiliser &
    le pointeur est une adresse? j'ai pas une très bonne idée sur les pointeur

    merci

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    j'ai utilisé gets au lieu de fgets! quel est la différence?
    Bonjour,

    Une différence de sécurité. Tu devrais toujours utiliser fgets(). Si tu veux plus de détails, tu peux lire cet article : https://gradot.wordpress.com/2013/05...-programmes-c/

  9. #9
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    j'ai utilisé gets au lieu de fgets! quel est la différence?
    Garde sous le coude ce lien très utile : cppreference.com . Attention à ne consulter que la section C, le site propose également une référence C++ qui hérite en partie du C et de sa bibliothèque.

    Lorsque tu as un doute sur le comportement de la bibliothèque standard, aie de suite le réflexe de jeter un coup d'œil à sa documentation. Exemple (en complément de l'article détaillé de Bktero) : gets et fgets.

  10. #10
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Bonjour,

    Une différence de sécurité. Tu devrais toujours utiliser fgets(). Si tu veux plus de détails, tu peux lire cet article : https://gradot.wordpress.com/2013/05...-programmes-c/
    j'ai croyé que le 'f' de 'fgets' c'est le 'f' de fichier
    merci

  11. #11
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 759
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    j'ai croyé que le 'f' de 'fgets' c'est le 'f' de fichier
    merci
    C'est le cas. Dans le cas d'une entrée via le clavier, le fichier à mettre est stdin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(var,sizeof(var),stdin)

  12. #12
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 752
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    @foetus : du moment où tu fais un strlen sur une chaîne, tu ne devrais plus avoir à invoquer aucun str*
    Je ne saisis pas le point

    Étant donné qu'en C la taille n'est pas associée à une chaîne de caractères, strlen peut être appelée assez souvent pour bien s'assurer de sa longueur.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Je crois que le point est "une fois que tu as obtenu la taille via strlen(), tu peux faire tes copies, concaténations etc. via memcpy() plutôt que str[n]cpy()."
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Tout-à-fait Médinoc.

    Si l'on considère les deux expressions suivantes, qui produisent exactement le même résultat :

    1. strcat(strcat(strcpy(buf, s1), s2), s3);
    2. const char *end = stpcpy(stpcpy(stpcpy(buf, s1), s2), s3);

    La première parcoure trois fois s1, deux fois s2, une fois s3. Et je ne connais toujours pas la longueur de ma chaîne ! Je peux ajouter un aux chiffres précédents si je veux obtenir cette information.

    La seconde parcoure une seule fois chacune des trois chaînes en entrée. J'ai déjà la longueur de ma chaîne : c'est (size_t)(end - buf).

  15. #15
    Inactif  
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Décembre 2017
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Décembre 2017
    Messages : 155
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	char ch1[50],ch2[50],ch5[50]; 
    	scanf("%s",ch1);
    Il n'y a aucune raison d'utiliser cette fonctionnalité "%s". Jamais.

    (hint: d'où sort le 50 dans la taille des tableaux?)

    Citation Envoyé par Automatiq Voir le message
    strcat ?
    Il n'y a aucune raison d'utiliser cette fonction strcat. Jamais. Utiliser memcpy.

    Citation Envoyé par edgarjacobs Voir le message
    2) scanf() attend un pointeur sur une adresse mémoire où seront stockées les données lues / interprétées; dans ce que tu montres, ch est déjà uin pointeur, donc pas besoin d'utiliser &
    NON

    C'est un tableau.

    Mais passé à une fonction, cela DEVIENT un pointeur.

  16. #16
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2015
    Messages : 64
    Par défaut
    Citation Envoyé par liberal1 Voir le message
    Il n'y a aucune raison d'utiliser cette fonctionnalité "%s". Jamais.

    (hint: d'où sort le 50 dans la taille des tableaux?)



    Il n'y a aucune raison d'utiliser cette fonction strcat. Jamais. Utiliser memcpy.
    1. pourquoi je ne dois pas utiliser %s!?
    2. la taille 50 de tableau: j'ai fais une allocation statique
    3. pourquoi je ne utilise pas strcat, et c'est quoi memcpy.

    merci

  17. #17
    Inactif  
    Homme Profil pro
    Architecte matériel
    Inscrit en
    Décembre 2017
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Architecte matériel

    Informations forums :
    Inscription : Décembre 2017
    Messages : 155
    Par défaut
    Citation Envoyé par Automatiq Voir le message
    1. pourquoi je ne dois pas utiliser %s!?
    2. la taille 50 de tableau: j'ai fais une allocation statique
    D'où sort ce 50?

    Comment sais-tu que ça va suffire?

    Citation Envoyé par Automatiq Voir le message
    3. pourquoi je ne utilise pas strcat, et c'est quoi memcpy.
    Parce qu'il n'y quasiment aucun cas où tu puisses l'utiliser correctement (où tu connais la taille à allouer) sans avoir la taille de la chaîne que tu étends et la taille de celle qui s'ajoute.

    Donc tu peux faire une copie de n octets au bon endroit. Tu ne passes pas par des fonctions str-quelque chose.

    De façon générale, si tu connais le nombre de caractères, tu n'as pas besoin de ces fonctions.

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Réponses: 2
    Dernier message: 18/10/2003, 14h42
  3. Chaînes de caractères
    Par Zazeglu dans le forum C
    Réponses: 3
    Dernier message: 28/08/2003, 16h20
  4. Inverser une chaîne de caractères
    Par DBBB dans le forum Assembleur
    Réponses: 2
    Dernier message: 30/03/2003, 11h09
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo