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 :

Arguments de la fonction main()


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2017
    Messages : 11
    Points : 10
    Points
    10
    Par défaut Arguments de la fonction main()
    Bonjour à tous,

    Je viens d'intégrer un IUT informatique en année spéciale, et je débute le C. Pour m'amuser (et m'entrainer) je me suis lancé dans l'écriture d'un programme de cryptage de données par la méthode du Chiffre de César (cryptage par décalage) qui consiste à décaler de x lettres chaque lettre. Petit exemple, on décale de 1 : "Salut" -> "Tbmvu" etc.

    Je rencontre un petit soucis au niveau des arguments de la fonction main, mon but est d'entrer en paramètres la clef de cryptage (1,2,3 ...) et le mot à crypter (SALUT...). J'aurai plus de mal à expliquer la source de mon problème que le compilateur. Voilà le code, si quelqu'un saurait d'où vient le problème, je lui crypte son pseudo gratuitement !

    Le compilateur renvoi "main.c|120|error: assignment to expression with array type|" . Pourtant ce sont deux chaines de caractères !

    Cordialement,
    Haz

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    #include <stdio.h>
    #include <stdbool.h>
     
    const char alphabet[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     
     
    bool isUpperCase (char message[]) {
      bool up = true;
      char c = message[0];
      int i = 0;
     
      while (up && c != '\0') {
        if (c != ' ') {
          int y = 0;
          bool isAlph = false;
     
          char alph = alphabet[0];
          while (!isAlph && alph != 0) {
            alph = alphabet[y];
            if (alph == c){
              isAlph = true;
            }
            y++;
          }
     
          if (!isAlph){
            up = false;
          }
        }
     
        i++;
        c = message[i];
      }
     
      return up;
    }
     
     
    int indexC (char c) {
      int ind = -1;
      bool isOK = false;
     
      while (!isOK) {
        ind++;
        if (c == alphabet[ind]) {
          isOK = true;
        }
      }
     
      return ind;
    }
     
     
    void chiffreCesar (char message[], int clef) {
      int i = 0;
      char c = message[0];
     
      while (c != '\0') {
        if (c != ' ') {
          int indexNewC = (indexC(c)+clef)%26;
          message[i] = alphabet[indexNewC];
        }
     
        i++;
        c = message[i];
      }
     
    }
     
     
    int power (int x, int n) {
      int result = 1;
      int i = 0;
     
      while (i<n) {
        result*=x;
        i++;
      }
     
      return result;
    }
     
     
    bool stringToInt (char chaine[], int *clef) {
      int result = 0;
      char c = chaine[0];
      int nbChar = 0;
      bool isOK = true;
     
      while (isOK && c != '0') {
        nbChar++;
        c = chaine[nbChar];
        if ('0' > c && c > '9') {
          isOK = false;
        }
      }
     
      while (isOK && nbChar > 0) {
        nbChar--;
        int val = (int)chaine[nbChar]-48;
        result += power(val,nbChar);
      }
     
      *clef = result;
      return isOK;
    }
     
     
    int main (int argc, char *argv[]) {
        char message[] = "Erreur";
        int clef = 0;
     
      if (argc == 3) {
        message = argv[1]; // C'est ici qu'à lieu l'accident ! *************************************************************************************
     
        if (isUpperCase(message)) {
          printf("%s est bien en majuscules !\n", message);
          chiffreCesar(message, clef);
          printf("%s est la version cryptée avec une clef qui vaut %d !\n", message, clef);
        }
        else {
          printf("%s n'est pas en majuscules !\n", message);
        }
      }
     
      else {
        printf("Veuillez indiquer deux paramètres tels que : ./cesar MOT clef\n");
      }
     
      return 0;
    }

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Il te manque des notions

    [...] <-

    Et avant que tu reviennes, le C ne gère que l'ASCII et seulement l'ASCII.
    Si tu veux des caractères accentués, au hasard , soit tu passes en UTF-16 avec le type wchar_t et les fonctions wcXXX (<- lien en anglais) soit tu passes par des API externes (celle de Microsoft, ICU, ...) soit tu fais ta propre gestion.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Citation Envoyé par Hazbury Voir le message
    Le compilateur renvoi "main.c|120|error: assignment to expression with array type|" . Pourtant ce sont deux chaines de caractères !
    Pas exactement.

    Un des premiers soucis auquel est confronté le débutant en C, c'est la manipulation d'une chaine de caractères. Parce que le concept "chaine" n'existe pas en tant qu'entité manipulable (par exemple interdit d'écrire if ("toto" == "toto")). Quand tu crois avoir une chaine entre les mains, en fait tu n'as que l'adresse de la case qui contient le premier caractère. Et comme les cases se suivent en mémoire, c'est alors suffisant pour pouvoir traiter toute la chaine (suffit de passer de case en case). Mais c'est à toi de faire ce travail (même si parfois tu croies ne pas le faire, c'est seulement parce que les fonctions que tu utilises le font à place).

    Pour faire simple: Tu peux écrire char *s="coucou". Dans ce cas, "s" pointe vers une zone statique de ton code, zone qui contient le caractère 'c'. Mais comme les caractères se suivent, la case suivante contient alors le caractère 'o' et etc. Tu peux donc afficher "s[x]" (un caractère) ou même directement "s" (parce que la fonction printf() s'occupera elle-même de boucler d'un caractère au suivant) mais tu ne peux pas modifier "s[x]" car la zone est statique (non modifiable).
    Tu peux aussi modifier "s" (dans le sens "le faire pointer vers autre chose") mais dans ce cas, tu as alors perdu toute référence à la zone qui contient "coucou", zone qui continuera quand-même d'exister jusqu'à la fin du programme mais pour rien car perdue.

    Tu peux aussi écrire char s[]="coucou". Dans ce cas, le compilateur remplace par char s[7]={'c', 'o', 'u', 'c', 'o', 'u', '\0'} (il détecte la taille nécessaire et remplit le tableau selon la syntaxe habituelle des tableaux initialisés à leur création). s est donc un tableau et tu peux accéder et modifier s[x] à ta guise (tant que "x" reste compris entre 0 et 6) mais tu ne peux pas modifier "s" lui-même (le nom d'un tableau est invariant).

    Tu peux rajouter ensuite, aux deux écritures précédentes, char *pt=s. "pt" récupère alors la valeur de "s". Et "s" c'est quoi ? C'est l'adresse du premier caractère du tableau. Donc "pt" récupère cette adresse.

    En écrivant char message[] = "Erreur" tu utilises la seconde écriture (tu crées un tableau). Mais tu ne peux pas modifier "message" car le nom d'un tableau est invariant d'où l'accident. Accessoirement, écrire var=truc puis (sans avoir traité "var") var=autre_chose devrait te mettre la puce à l'oreille sur ta compréhension de ce que représente "var". Et (accessoirement bis), écrire var=truc puis var2=var (alors que t'as pas l'intention de modifier "var") devrait là aussi te mettre la puce à l'oreille sur ta façon d'organiser tes variables (si j'ai des pièces dans la poche gauche, je n'ai alors pas besoin de les copier/déplacer dans la poche droite pour m'en servir).

    Donc en fait t'as pas besoin de "message" car tu ar déjà "argv[1]". Mais si malgré tout tu veux que "message" contienne la chaine contenue dans "argv[1]", soit tu copies cette chaine octet par octet (ou alors tu utilises strcpy() qui fait ce travail pour toi), soit tu définis "message" non plus comme un tableau mais comme un pointeur (rappel: un pointeur c'est juste une variable apte à contenir une adresse) et tu lui mets alors argv[1] (qui, représentant une chaine, est en fait lui aussi rien d'autre qu'une adresse).

    Et pour en revenir au début du paragraphe, si tu écris if ("toto" == "toto") tu ne feras en fait que comparer deux adresse de deux zones statiques différentes (donc deux adresses différentes).

    PS: et sémantiquement, on n'utilise pas le mot "cryptage" mais "chiffrement". Parce que si le mot "déchiffrement" désigne la technique de récupération d'un message via la clef (parce qu'on est le destinataire légitime du message), et que "décryptage" désigne la technique de récupération d'un message sans avoir la clef (par "cassage" du code parce qu'on n'est pas le destinataire légitime du message mais qu'on veut quand-même le connaitre), alors par antonymie le terme "cryptage" serait la technique de création un message chiffré sans avoir sa clef de chiffrement ce qui est alors totalement aussi inutile qu'impossible.

    Citation Envoyé par Hazbury Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int indexC (char c) {
      int ind = -1;
      bool isOK = false;
     
      while (!isOK) {
        ind++;
        if (c == alphabet[ind]) {
          isOK = true;
        }
      }
     
      return ind;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int indexC (char c) {
      int ind;
      char *pt;
      for (pt=alphabet, ind=0; *pt != '\0'; pt++, ind++) {
        if (c == *pt) return ind;
      }
      return -1;
    }
    Et si t'as le droit d'utiliser des fonctions de la librairie standard
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int indexC (char c) {
      char *pt=strchr(alphabet, c);
      return pt != NULL ?pt - alphabet :-1;
    }
    Citation Envoyé par Hazbury Voir le message
    Code c : 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
    bool isUpperCase (char message[]) {
      bool up = true;
      char c = message[0];
      int i = 0;
     
      while (up && c != '\0') {
        if (c != ' ') {
          int y = 0;
          bool isAlph = false;
     
          char alph = alphabet[0];
          while (!isAlph && alph != 0) {
            alph = alphabet[y];
            if (alph == c){
              isAlph = true;
            }
            y++;
          }
     
          if (!isAlph){
            up = false;
          }
        }
     
        i++;
        c = message[i];
      }
     
      return up;
    }
    Là franchement je panne que dalle à ce que fait cette fonction. Il me semble d'après son nom qu'elle vérifie si le message est en majuscules (heureusement donc que le nom est significatif de l'action => bon point pour toi). Mais si c'est juste ça...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool isUpperCase (char message[]) {
      char *pt;
      for (pt=message; *pt != '\0'; pt++) {
        if (indexC(*pt) == -1) return false;  // Ben oui, t'as une fonction qui regarde si "c" est dans alphabet (majuscules) et tu veux regarder si tous les "c" de "message" sont en majuscules =>autant factoriser les traitements identiques...
       // Si ensuite tu veux gérer le cas "espace" à part (tu le testes dans ta fonction initiale) ben tu rajoutes simplement un test
      }
      return true;
    }
    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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2017
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Waw ! Déjà merci beaucoup pour ces réponses très complètes ! Je crois que je commence à comprendre les notions de pointeurs. J'ai réussi à utiliser argv[1] en créant un pointeur *message qui va récupérer l'adresse de argv[1] (si j'ai bien compris, en tout cas, ça fonctionne !)

    J'ai donc essayé de faire de même avec un pointeur pour récupérer l'adresse de argv[2] avant de le traiter, comme pour argv[1], mais je retombes sur un problème presque similaire... Etant donné que argv[2] renvoie une adresse liée au premier caractère d'une chaine, il faut que je transforme ça en entier, pour m'en servir par la suite (c'est la clef de chiffrement).

    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
    bool stringToInt (char chaine[], int *clef) {
      int result = 0;
      char c = chaine[0];
      int nbChar = 0;
      bool isOK = true;
     
      printf("%s\n", c);
     
      while (isOK && c != '0') {
        nbChar++;
        c = chaine[nbChar];
        if ('0' > c && c > '9') {
          isOK = false;
        }
      }
     
      while (isOK && nbChar > 0) {
        nbChar--;
        int val = (int)chaine[nbChar]-48;
        result += power(val,nbChar);
      }
     
      *clef = result;
      return isOK;
    }
     
    int main (int argc, char *argv[]) {
        int clef = 0;
     
      if (argc == 3) {
        char *message = argv[1];
        stringToInt(argv[2],&clef);
     
        if (isUpperCase(message)) {
          printf("%s est bien en majuscules !\n", message);
          chiffreCesar(message, clef);
          printf("%s est la version cryptée avec une clef qui vaut %d !\n", message, clef);
        }
        else {
          printf("%s n'est pas en majuscules !\n", message);
        }
      }
     
      else {
        printf("Veuillez indiquer deux paramètres tels que : ./cesar MOT clef\n");
      }
     
      return 0;
    }
    La fonction isUpperCase sert effectivement à détecter si la chaine envoyée par l'utilisateur est en majuscule, cela réduit le nombre de cas à traiter (moins de caractères ASCII)

    PS : J'ai volontairement effectué toutes les fonctions à la main, pour m'entrainer, c'est pour cela que je n'utilise pas de fonctions déjà existantes des librairies.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hazbury Voir le message
    J'ai réussi à utiliser argv[1] en créant un pointeur *message qui va récupérer l'adresse de argv[1] (si j'ai bien compris, en tout cas, ça fonctionne !)
    Exact. Mais tu aurais utilisé à la place argv[1] cela aurait fonctionné aussi. Comme je le disais tantôt, si tu écris var=123 puis var2=var alors "var2" est inutile puisque "var" suffit.

    Citation Envoyé par Hazbury Voir le message
    J'ai donc essayé de faire de même avec un pointeur pour récupérer l'adresse de argv[2] avant de le traiter, comme pour argv[1], mais je retombes sur un problème presque similaire... Etant donné que argv[2] renvoie une adresse liée au premier caractère d'une chaine, il faut que je transforme ça en entier, pour m'en servir par la suite (c'est la clef de chiffrement).
    Je comprends le souci (transformer par exemple "123" en 123) car tu n'es pas le premier à y être confronté. Je te parlerais bien de atoi() ou strtoul() mais comme tu veux tout faire...

    Citation Envoyé par Hazbury Voir le message
    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
    bool stringToInt (char chaine[], int *clef) {
      int result = 0;
      char c = chaine[0];
      int nbChar = 0;
      bool isOK = true;
     
      printf("%s\n", c);
     
      while (isOK && c != '0') {
        nbChar++;
        c = chaine[nbChar];
        if ('0' > c && c > '9') {
          isOK = false;
        }
      }
     
      while (isOK && nbChar > 0) {
        nbChar--;
        int val = (int)chaine[nbChar]-48;
        result += power(val,nbChar);
      }
     
      *clef = result;
      return isOK;
    }
    Une fonction presque de qualité
    En première lecture je me suis dit "c'est dommage de lui passer l'adresse où stocker le nombre vu qu'elle pourrait renvoyer ledit nombre" mais ensuite j'ai vu qu'elle renvoyait un flag ok/ko indiquant si la conversion s'était bien passée

    Mais bon, j'ai quand-même dit "presque" car ta seule (mais énorme) erreur, c'est ce if ('0' > c && c > '9') (réfléchis un petit peu sur le fait qu'un chiffre puisse être plus petit que 0 et plus grand que 9 puis va relire les lois de "De Morgan"...). Et ce "48" n'est pas très adéquat (il est correct mais les devs n'aiment pas ce qu'on nomme des "valeurs magiques" => valeurs ayant une signification sur le moment mais susceptible d'évoluer et de toute façon nécessitant une gymnastique mentale pour la comprendre).
    Et ta fonction reste un peu inutilement complexe (par exemple appeler power là où une simple multiplication par 10 suffit) mais c'est simplement un manque d'habitude et non un manque de motivation donc ça s'arrangera très facilement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    bool stringToInt (char chaine[], unsigned short *clef) {
    	char *pt;
    	unsigned short result=0;
    	for (pt=chaine; *pt != '\0'; pt++) {
    		if (*pt < '0' || *pt > '9')  // if (!isdigit(*pt))
    			return false;
    		result=result * 10 + (*pt) - '0';
    	}
    	*clef=result;
    	return true;
    }
    Citation Envoyé par Hazbury Voir le message
    J'ai volontairement effectué toutes les fonctions à la main, pour m'entrainer, c'est pour cela que je n'utilise pas de fonctions déjà existantes des librairies.
    C'est compréhensible. Mais tu devrais quand-même t'autoriser à réutiliser tes propres fonctions
    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
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Bonjour,

    Citation Envoyé par foetus Voir le message
    message, c'est un pointeur constant (immuable) vers une chaîne de caractères C
    Dans main, il a écrit char message[] = "Erreur";.
    Donc cette variable message est de type tableau de 7 char, pas de type pointeur.
    Pour t'en convaincre, tu peux voir que sizeof(message) vaut 7.
    Mais Sve@r a déjà détaillé cela.

    Citation Envoyé par foetus Voir le message
    En créant un tableau avec une taille assez grande char* my_str[80] = {0}
    Attention, tu viens de déclarer un tableau de 80 pointeurs.

    Citation Envoyé par foetus Voir le message
    Et avant que tu reviennes, le C ne gère que l'ASCII et seulement l'ASCII.
    Depuis C11, il gère aussi l'UTF-8 : u8"Ceci est une chaîne UTF-8 en langage C.".
    Plus de détails : https://en.cppreference.com/w/c/language/string_literal

    Citation Envoyé par foetus Voir le message
    Si tu veux des caractères accentués, au hasard , soit tu passes en UTF-16 avec le type wchar_t
    À ma connaissance, il n'y a que sur Windows que wchar_t fait 16 bits. Ailleurs, il fait 32 bits.
    Si on veut stocker des unités de codage en UTF-16, alors il faut utiliser char16_t, apparu en C11.

    Citation Envoyé par Sve@r Voir le message
    si tu écris if ("toto" == "toto") tu ne feras en fait que comparer deux adresse de deux zones statiques différentes (donc deux adresses différentes).
    Pas forcément. Ces deux zones mémoire peuvent être identiques.

    Extrait de la page https://en.cppreference.com/w/c/language/string_literal :
    It is neither required nor forbidden for identical string literals to refer to the same location in memory. Moreover, overlapping string literals or string literals that are substrings of other string literals may be combined.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "def" == 3+"abcdef"; // may be 1 or 0, implementation-defined
    +1 quand même, car le reste du message est bon.

    Citation Envoyé par Hazbury Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const char alphabet[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    Attention, si tu choisis comme taille 26 au lieu de 27, alors il manquera le caractère '\0' à la fin de ton tableau, ce qui est dangereux. Le code que t'a écrit Sve@r est correct, mais à condition que la chaîne du tableau alphabet se termine par '\0'.
    Avec un tableau alphabet de taille 26, il se peut que ton code fonctionne quand même si l'octet qui suit ton tableau alphabet a tous ses bits à 0, mais alors ça ne marchera que par chance.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Pyramidev Voir le message
    Dans main, il a écrit char message[] = "Erreur";Donc cette variable message est de type tableau de 7 char, pas de type pointeur.
    Pour t'en convaincre, tu peux voir que sizeof(message) vaut 7.
    Mais Sve@r a déjà détaillé cela.
    Suppression de mon message , mais à chaque fois entre char* str = "Bonjour"; et char str[] = "Bonjour"; je ne sais jamais qui est modifiable ou pas ? le pointeur, le tableau ou la chaîne de caractères.
    Et cela a beau être un tableau, le pointeur est immuable puisque le compilateur te génère une erreur.


    Citation Envoyé par Pyramidev Voir le message
    Depuis C11, il gère aussi l'UTF-8 : u8"Ceci est une chaîne UTF-8 en langage C.".
    Plus de détails : https://en.cppreference.com/w/c/language/string_literal[/C].
    Tant que les conversions ne seront pas implicites, ce sera une solution pas terrible u8char str[] = L"Bonjour" ou wchar_t str[]= u8"Bonjour".
    Voire peut-être pire parce que tu multiplies les types alors qu'avec un char* tu peux tout gérer.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    mais à chaque fois entre char* str = "Bonjour"; et char str[] = "Bonjour"; je ne sais jamais qui est modifiable ou pas ? le pointeur, le tableau ou la chaîne de caractères.
    https://www.developpez.net/forums/d1.../#post10595432

    Citation Envoyé par Pyramidev Voir le message
    Pas forcément. Ces deux zones mémoire peuvent être identiques.
    Elles ont beau être identiques, elles sont (à priori) stockées à deux emplacements différent. Et même si (idée) l'optimiseur détectait l'égalité et décide de n'en stocker alors qu'une seule, ça reste inadéquat d'écrire le test de cette façon

    Citation Envoyé par Pyramidev Voir le message
    Référence C++. Ici on est en C

    Citation Envoyé par Pyramidev Voir le message
    +1 quand même, car le reste du message est bon.


    Citation Envoyé par Pyramidev Voir le message
    Attention, si tu choisis comme taille 26 au lieu de 27, alors il manquera le caractère '\0' à la fin de ton tableau, ce qui est dangereux. Le code que t'a écrit Sve@r est correct, mais à condition que la chaîne du tableau alphabet se termine par '\0'.
    Avec un tableau alphabet de taille 26, il se peut que ton code fonctionne quand même si l'octet qui suit ton tableau alphabet a tous ses bits à 0, mais alors ça ne marchera que par chance.
    Comment ai-je pu laisser passer ça ??? @svear =>
    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]

  9. #9
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Référence C++. Ici on est en C
    J'ai cité le bon lien.
    Chaînes littérales en C : https://en.cppreference.com/w/c/language/string_literal
    Chaînes littérales en C++ : https://en.cppreference.com/w/cpp/la...string_literal

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

Discussions similaires

  1. Comment mettre des arguments dans la fonction principale main()?
    Par oumouRaby dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 18/07/2016, 14h00
  2. Argument de la fonction main
    Par membreComplexe12 dans le forum C++
    Réponses: 15
    Dernier message: 18/11/2010, 17h26
  3. Réponses: 4
    Dernier message: 14/03/2009, 19h56
  4. arguments dans ma fonction main
    Par salseropom dans le forum C
    Réponses: 10
    Dernier message: 15/03/2006, 23h12
  5. passer FILE* en argument d une fonction
    Par Monsieur_Manu dans le forum C
    Réponses: 9
    Dernier message: 10/04/2003, 17h56

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