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 :

Concaténation de char


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 74
    Par défaut Concaténation de char
    Bonjour, bonsoir a tous et a toutes.
    Je m’attelle depuis hier à mon premier programme en C.
    Après avoir eu du mal a comprendre la typage (que je ne crois pas avoir pleinement compris) c'est a la concaténation de char que je me frotte, car après avoir découvert le vrai visage des char ... cela ce révèle plus compliqué.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    #include <stdio.h>
    #include <time.h>
     
    // Un caractère au random
    char randomOne()
    {
        int randResult = rand() % (40 + 1);
        int randCara;
     
        char alphaMin[] = "abcdefghijklmnopqrstuvwxyz";
        char alphaMaj[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char specialCara[] = "&~#'{([-|_@)]=}+$%*!:/;.,?";
        char result;
     
        if(randResult < 11)
        {
            randCara = rand() % (25 + 1);
            result = alphaMin[randCara];
        }
        else if(randResult < 21)
        {
            randCara = rand() % (25 + 1);
            result = alphaMaj[randCara];
        }
        else if(randResult < 31)
        {
            result = rand() % (9);
        }
        else
        {
            randCara = rand() % (26 + 1);
            result = specialCara[randCara];
        }
     
        return result;
    }
     
    int main(int argc, char *argv[])
    {
        int totalSize = atoi(argv[1]);
        int count = 0;
     
        char pwd;
     
        // Initialise rand seed
        srand(time(NULL));
     
        if(argc != 2)
        {
            printf("Use one argv. No more \nGenCryPWD [CodeSize/max250]");
            return 0;
        }
     
        // Construction du pwd
        while(count < totalSize)
        {
            if(count == 0)
            {
                pwd = randomOne();
            }
            else
            {
                pwd = pwd + randomOne();
            }
     
            ++count;
        }
     
        printf("%c", pwd);
     
        return 0;
    }
    C'est donc la ligne "pwd = pwd + randomOne();" qui me pose problème.
    J'avais choisi de réaliser un petit générateur de mot de passe ... cela me semblait être un exercice for simple pour une première en C venant de php.
    Grossière erreur

    Preneur de toute remarque et aide, merci.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Je te conseille de mettre la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int totalSize = atoi(argv[1]);
    après celles-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        if(argc != 2)
        {
            printf("Use one argv. No more \nGenCryPWD [CodeSize/max250]");
            return 0;
        }
    Afin de vérifier avant que l'utilisateur a bien rentré l'argument.

    Pour le reste, ton erreur est de vouloir utiliser un char pour tout stocker.
    En effet, un char ne pourra jamais contenir qu'un seul char, ou caractère, mais en aucune façon une chaine de caractères entière !
    Tu auras besoin d'un tableau de char pour cela, de taille statique (il y aura alors un maximum de caractères à fixer) ou dynamique : la taille se fixée à l'exécution.
    Autre chose, il n'y a pas d'opérateur + tel que tu souhaites l'utiliser ici en C, il te faudra remplir chaque case du tableau et y accédant par tableau[position] = caractere;.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 859
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par papaye0 Voir le message
    C'est donc la ligne "pwd = pwd + randomOne();" qui me pose problème.
    J'avais choisi de réaliser un petit générateur de mot de passe ... cela me semblait être un exercice for simple pour une première en C venant de php.
    Grossière erreur
    Salut

    En effet, ta grossière erreur a été de considérer le C comme php.
    Le php est un langage dit "évolué". C'est à dire qu'il adapte ses opérations aux éléments qu'il manipule. Ainsi en php, 2+2 donne 4 mais "toto"+"titi" donne "tototiti".

    Le C, lui, est un langage super bas niveau, à la limite de l'assembleur. En C, 2+2 donnera 4 mais "toto"+"titi" donnera un simple nombre (dont le calcul semble aléatoire mais qui en réalité peut être prévu) et absolument pas "tototiti".
    Et en C, 'a' + 1 donnera 'b' (parce que le code ascii de 'b' se trouve à une unité de celui de 'a'). Et si tu veux vérifier que tu as bien compris le calcul avec les char, essaye de trouver combien font '9' - '0'.

    Tout ça pour dire que si tu veux concaténer "titi" avec "toto", il te faudra
    1. créer un tableau suffisant pour tout contenir
    2. y stocker "toto" caractère par caractère
    3. y rajouter "titi" 'de la même façon


    Bref ce qui peut prendre une simple instruction en php prendra bien souvent une vingtaine de lignes en C. Mais, en retour, tu auras un programme C fonctionnant 1000 fois plus vite qu'un même programme php. Ce n'est pas que l'un soit mieux ou moins bien que l'autre, c'est que chacun ont leurs avantages et inconvénients et chacun est plus ou moins en adéquation avec un travail ou un autre...

    PS: ceci dit, il existe dans la librairie C des fonctions déjà toutes faites permettant de copier, comparer, concaténer des chaines. Mais ces fonctions font ce travail au tout aussi bas niveau que ce que tu aurais dû faire...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 74
    Par défaut
    Merci pour vos réponses, c'est ce que j'avais cru comprendre.
    Quelque modif de mon code, ce qui nous donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    // Un caractère au random
    char randomOne()
    {
        int randResult = random() % (40 + 1);
        int randCara;
     
        char alphaMin[] = "abcdefghijklmnopqrstuvwxyz";
        char alphaMaj[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char specialCara[] = "!#$%&'()*+,-.@[]^_";
        char result;
     
        if(randResult < 11)
        {
            randCara = random() % (25 + 1);
            result = alphaMin[randCara];
        }
        else if((randResult < 21) && (randResult > 11))
        {
            randCara = random() % (25 + 1);
            result = alphaMaj[randCara];
        }
        else if((randResult < 31) && (randResult > 21))
        {
            result = random() % (9) + '0';
        }
        else
        {
            randCara = random() % (17 + 1);
            result = putchar(specialCara[randCara]);
        }
     
        return result;
    }
     
    int main(int argc, char *argv[])
    {
        // Initialise rand seed
        srandom(time(NULL));
     
        if(argc != 2)
        {
            printf("Use one argv. No more \nGenCryPWD [CodeSize/max250]");
            return 0;
        }
     
        int totalSize = atoi(argv[1]);
        int count;
     
        char pwd[250];
     
        // Construction du pwd
        for(count = 0; count < totalSize; ++count)
        {
            pwd[count] = randomOne();
        }
     
        printf("%s", pwd);
     
        return 0;
    }
    J'avais deja testé la ligne 58 (d'ou mon post), mais avais oublié de compiler ...
    En revanche j'ai en sortie des "�", alors que j'ai bien fait attention a utiliser les char de la table ascii. j'ai réalisé des testes avec // les les lignes 19-24-33 en les dé-commentant les une après les autres afin de voir d'ou viens le problème mais il y a toujours un "�" qui s'affiche a un endroit du passwd.

    ex avec './a.out 10' :
    [['Lj[R[nr5'e�.�
    %@6%@4jh3Le1���
    [![J018G!ITc�7C
    s5SyrcPF6KJ/.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 859
    Billets dans le blog
    1
    Par défaut
    Salut
    En dehors de la signification de tes nombres (pourquoi ces "25 + 1" ou ces "11"), je ne m'explique pas ce putchar() ligne 33 (je l'ai surligné en rouge dans ton code)...

    Sinon, quand on construit une chaine "à la main" (comme tu le fais avec ta boucle), il ne faut pas oublier d'y positionner en final un caractère '\0' car sinon printf("%s") ne sait pas où s'arrêter. Et si tu ne connais pas cette particularité, je te conseille alors de t'informer sur la façon dont le C conçoit et manipule ses strings.

    Pour ton code rajoute pwd[count] = '\0' en fin de for().
    Tu peux aussi, pour montrer que tu maitrises parfaitement la position du '\0', remplacer cette instruction par pwd[totalSize] = '\0' et dans ce cas tu peux même la mettre avant le for()...

    PS: pour avoir un aléa entre min et max (inclus), il y a 2 façons de faire
    1. demander random() % (max - min + 1) + min
    2. demander random() / (RAND_MAX + 1.0) * (max - min + 1) + min

    La seconde façon étant souvent plus conseillée que la première question "uniformisation" des nombres tirés...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 74
    Par défaut
    L'erreur venait effectivement du '\0'. Je ne savais pas du tout, au passage génial le pwd[totalSize] = '\0'; Très malin !

    Les 11 était là pour tester le comportement de If en C, les +1 une idiotie ... le putchar une tentative pour trouver une solution, qui ne venait pas de là.

    Encore merci a vous.

    Si vous aviez des liens sur les bonnes pratiques en C, des divers lib de base etc ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Opérateur de concaténation pour char *
    Par yves042 dans le forum C++
    Réponses: 2
    Dernier message: 06/05/2010, 10h12
  2. Réponses: 5
    Dernier message: 20/03/2009, 18h16
  3. concaténation de char*
    Par Jérémy Lefevre dans le forum C
    Réponses: 58
    Dernier message: 11/11/2006, 10h12
  4. [C++] Concaténer un char[50] avec un int
    Par Invité4 dans le forum C++
    Réponses: 10
    Dernier message: 07/04/2006, 14h54
  5. concaténation de char et float
    Par gup dans le forum C
    Réponses: 11
    Dernier message: 31/12/2005, 00h15

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