je viens de débuter le language C, j'utilise Visual Studio comme IDE, et dans mon programme j'ai créé une fonction pour copier un chaîne de caractères (un tableau de chars) dans une autre chaîne de caractères, car strcpy() ne marche plus.
Sauf mon code lève une exception. (Exception levée à 0x00007FF64E901C0F dans Programme.exe : 0xC0000005 : Violation d'accès lors de l'écriture à l'emplacement 0x0000000000000000.)
Pourtant j'ai juste fait une boucle for qui parcourt le tableau, je ne vois donc pas ce qui cloche.
Voilà mon code:
void copierString(char* destination[], const char* source[], int tailleTableau)
{
for (int i = 0; i < tailleTableau; i++)
{
destination[i] = source[i];
}
}
Merci d'avance pour votre réponse,
SniffierPond
- Edité par SniffierPond 23 décembre 2021 à 17:52:29
Ce qui est étrange c'est d'avoir un tableau de pointeur. En tout cas tu exposes pas tout ton code pour voir ce qui n'est pas bon. Concernant une copie de chaine on peut faire beaucoup plus simple :
strcpy ne marche plus ? Allons voyons, c'est une blague ?
Pourquoi tes paramètres destination et source sont des pointeurs de pointeur sur char si tu ne souhaites que copier une chaîne de caractère dans une autre ?
À mon avis si montrais l'intégralité de ton code ainsi que les warnings tu comprendrais qu'il y a quelque chose qui ne va pas. Ou alors ta fonction est très mal nommée.
git is great because Linus did it, mercurial is better because he didn't.
On a des tableaux de pointeurs (en tout cas, c'est ce que la fonction montre). On risque facilement de se retrouver dans la nature de cette façon. char dst[] et const char src[] devraient fonctionner. @markand: c'est un peu tordu pour un débutant: assignation, incrémentation et comparaison dans le même énoncé ...
Le Tout est souvent plus grand que la somme de ses parties.
Alors quelle est la syntaxe pour avoir un pointeur sur un tableau qui me permet de le manipuler depuis ma fonction?
Hein ??? Tu n'as pas besoin d'avoir un pointeur sur un tableau pour manipuler le tableau depuis la fonction !
Tu as remarqué que 'strcpy' ne marche plus (c'est une boutade !) et tu veux écrire une fonction qui la remplace. Donc son prototype sera :
void copierString(char destination[], const char source[], int tailleTableau)
(Il existe une autre possibilité, peu importe).
Et là ça marchera.
(Les autres : vous comprenez pourquoi je trouve que ce n'est pas utile de parler de pointeurs quand on fait des opérations basiques sur les tableaux (cf discussion citée par Pierrot) ? Là j'ai l'impression que SniffierPond a lu que, quand on passe un tableau en paramètres, la fonction utilise un pointeur vers le début du tableau, et ça l'a bien embrouillé.)
Comme tu débutes, je suppose que le programme ne doit pas être trop conséquent. Je te conseille de poster l'intégralité du code pour que nous puissions t'aider.
- Edité par edgarjacobs 23 décembre 2021 à 20:12:26
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Pourtant, voici un programme où des fonctions manipulent des tableaux :
#include <stdio.h>
#define N 200
void init_tab(int tab[N], int nb_elem)
{ /* Initialise un tableau avec les carrés */
for (int i = 1; i <= nb_elem; i++)
tab[i-1] = i*i;
}
void fois_deux(int tab1[N], int tab2[N], int nb_elem)
{ /* Double les valeurs des éléments */
for (int i = 0; i < nb_elem; i++)
tab2[i] = 2.0 * tab1[i];
}
void affiche(int tab[N], int nb_elem)
{ /* Affiche les éléments du tableau en ligne */
printf("[ ");
for (int i = 0; i < nb_elem; i++)
printf("%d ", tab[i]);
printf("]\n");
}
int main(void)
{
int tableau[N];
int tableaudouble[N];
init_tab(tableau, 5);
affiche(tableau, 5);
fois_deux(tableau, tableaudouble, 5);
affiche(tableaudouble, 5);
return 0;
}
De mon point de vue, il n'y a que des tableaux, aucun pointeur, je n'ai même pas besoin d'avoir suivi un cours sur les pointeurs pour faire ça.
Après, je sais bien que dans les fonctions, ce sont des pointeurs vers le début des tableaux (donc pas des pointeurs sur tableaux mais bien des pointeurs sur 'int'). Mais ça, c'est la petite cuisine interne du C. Alors oui, le C est un langage qui nécessite souvent de mettre les mains dans le cambouis et d'utiliser cette petite cuisine interne. Ce n'est pas obligatoire dans ce contexte, ni (je trouve) celui de SniffierPond qui souhaite ré-écrire 'strcpy'.
Ah, je m'explique mal. De mon point de vue signifiait : vu depuis ma position. Ce n'est pas une question d'opinion mais de position. Je n'ai déclaré aucun pointeur, je n'ai pas utilisé de * ni de &.
Du point de vue du compilateur (depuis sa position), il y a bien sûr plein de pointeurs. Mais je n'ai pas à m'en soucier.
tu as plusieurs problèmes, mais le principal est un problème de compréhension autant de comment on représente une chaîne de caractères que «qui fait quoi à quel moment».
Tout d'abord tu dis :
SniffierPond a écrit:
Bonjour,
je viens de débuter le language C, j'utilise Visual Studio comme IDE, et dans mon programme j'ai créé une fonction pour copier un chaîne de caractères (un tableau de chars) dans une autre chaîne de caractères, car strcpy() ne marche plus.
ok … «strcpy ne marche plus» … tu devrais plutôt dire «j'ai un problème d'utilisation de strcpy» car si strcpy ne fonctionnait plus alors la majorité des programmes de base ne fonctionneraient plus non plus.
Tu dis également «j'ai créé une fonction pour copier un chaîne de caractères (un tableau de chars) dans une autre chaîne de caractères». Tu parles de «tableau de char» ce qui se traduit par «char destination[]» or dans ce que tu nous montre on trouve «char *destination[]» qui définit destination comme étant un tableau sur des éléments qui ont pour type char * = pointeur sur char …
Tu dis également :
SniffierPond a écrit:
[...]
Sauf mon code lève une exception. (Exception levée à 0x00007FF64E901C0F dans Programme.exe : 0xC0000005 : Violation d'accès lors de l'écriture à l'emplacement 0x0000000000000000.)
avec :
SniffierPond a écrit:
[...] Et le compilateur lève une exception pile à la ligne :
destination[i] = source[i];
Ce n'est pas le compilo qui lève une exception … mais l'OS qui intercepte une exception levée par le programme compilé lorsqu'il est exécuté.
Le compilo t'aura sans doute émit quelques warnings … tout au plus.
Si tu veux créer une fonction copierString qui prend un tableau de char sourcede longueur tailleTableau et en copie le contenu dans un tableau de char destination (de taille suffisante) alors il te faudra écrire :
voidcopierString(char destination[], const char source[], int tailleTableau) {
Et on va partir la discussion sur ce qu'est un "tableau de char" et une "chaîne de char" dont la seule différence est la présence d'un caractère de fin de chaîne représenté par '\0' qui vaut 0 de toute façon. Et pourquoi strcpy ne marche plus? N'est-ce pas parce qu'on n'a pas de caractère de fin de chaîne?
Le langage C amène lui-même une confusion. Je peux avoir char dst[] ou char *dst dans le prototype et utiliser *dst ou dst[i] dans la fonction, c'est interchangeable. (voir le code de markand) Comment voulez-vous qu'un débutant s'y retrouve?
- Edité par PierrotLeFou 24 décembre 2021 à 1:50:11
Le Tout est souvent plus grand que la somme de ses parties.
Pierrot, quelqu'un qui écrit en Français «tableau de char» mais en C «char * truc[]» a forcément un gros problème de compréhension concernant les types (peu importe que le représentation usuelle des chaînes se fasse en ASCIIZ dans la libc via la famille de fonctions str*).
Pierrot, quelqu'un qui écrit en Français «tableau de char» mais en C «char * truc[]» a forcément un gros problème de compréhension concernant les types (peu importe que le représentation usuelle des chaînes se fasse en ASCIIZ dans la libc via la famille de fonctions str*).
J'y vois une confusion avec les deux façons (équivalentes) de déclarer la fonction :
fonction(char tableau[])
et
fonction(char *tableau)
----------------------------
rouIoude a écrit:
robun a écrit:
Je n'ai déclaré aucun pointeur
Ça aussi c'est faux !
D'un point de vue sémantique (donc du point de vue humain) c'est vrai. Du point de vue du compilateur, je m'en fiche, c'est son problème. (Je m'en fiche dans ce contexte, où je n'ai pas besoin de savoir que c'est en réalité un pointeur qui est utilisé dans la fonction.)
Tu t'en fiche, ok, mais traiter le pointeur comme un pointeur est parfois très pratique, Si je prend la fonction strcpy comme l'as écris markand j'écris comment ? Comme ça :
Ah oui, les pointeurs sont très pratiques ! L'exemple de markand est en effet éloquent. Et je suis sûr qu'un professionnel doit faire ainsi. Mais ce n'est pas la méthode qu'avait utilisée au début SniffierPond, qui a dit être débutant. Je trouve que pour corriger son programme, les pointeurs n'étaient donc pas nécessaires.
Quant à s'interdire d'utiliser le C si on ne veut pas utiliser de pointeurs, je fais ce que je veux ! En fait, pour mes projets personnels, j'utilise le C principalement parce que c'est le langage avec lequel je suis le plus à l'aise pour faire de la programmation structurée. Il me semble que le C n'est pas qu'un assembleur de haut niveau, il a d'autres qualités.
Je trouve que pour corriger son programme, les pointeurs n'étaient donc pas nécessaires.
Faudrait déjà savoir ce qu'il lui envoi à sa fonction ? Parce que pour que ça ne marche pas avec strcpy ?!?
robun a écrit:
Là j'ai l'impression que SniffierPond a lu que, quand on passe un tableau en paramètres, la fonction utilise un pointeur vers le début du tableau, et ça l'a bien embrouillé.)
C'est pourtant la vérité ! Et :
SniffierPond a écrit:
Au fait j'essaye juste d'accéder à la ligne d'un tableau avec son adresse passée en paramètre de la fonction.
Il a bien conscience de passer l'adresse du tableau (adresse de son premier élément).
Sinon comment la fonction pourrait modifier le tableau passé en paramètre ? Ça ne serait plus cohérent avec les autres type de variable.
Notez toutefois que même si un tableau peut être converti en pointeur ça reste des déclarations différentes. Une fonction qui prend un tableau a besoin de connaitre la définition de l'objet et ça c'est pas pratique.
Alors c'est intéressant comme comportement car cela ne devrait pas arriver en fait. On peut le constater avec gcc et clang mais pas icc (le compilo Intel) ni msvc … (testé sur godbolt).
Le pourquoi cela ne devrait pas se produire est simple. La norme à la section 6.7.6.3 Function declarators spécifie :
à l'alinéa 12 : « If the function declarator is not part of a definition of that function, parameters may have incomplete type [...] » ;
à l'alinéa 4 : « After adjustment, the parameters in a parameter type list in a function declarator that is part of a definition of that function shall not have incomplete type.» où l'alinéa 7 précise : «A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’ [...]»
Ces interprétations différentes pourraient provenir d'une interprétation de la section 6.2.1 Scope of Identifiers où l'alinéa 4 spécifie la visibilité des paramètres lors d'une définition ou d'une déclaration sans préciser l'ajustement éventuel des paramètres de type (tableau de …).
Notez toutefois que même si un tableau peut être converti en pointeur ça reste des déclarations différentes. Une fonction qui prend un tableau a besoin de connaitre la définition de l'objet et ça c'est pas pratique.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
git is great because Linus did it, mercurial is better because he didn't.
git is great because Linus did it, mercurial is better because he didn't.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
git is great because Linus did it, mercurial is better because he didn't.