Pointeurs char, char* et tableau [Résolu]

Signaler
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008
-
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008
-
'lut

j'ai un probleme avec des chaines de caracteres, tableaux de chaines et autres joyeusetées

c'est pour un hiscore. je ne sais pas si la manière de faire est la bonne, ou si il y en a de meilleur, mais avec ma methode, je n'arrive pas à copier dans le tableau de char tel qu'il est fait.
je suis tout ouïe pour une autre solution

voilà mes datas : les scores sont préremplis au demarrage ou chargé si fichier de scores.

char *names[]={
"NOM JOUEUR 1",
"NOM JOUEUR 2",
"............................",
etc... il y a 10 noms
};

l'affichage, la sauvegarde... fonctionnent en utilisant le contenu par names[i]
mais quand je copie ça marche pour les noms de 0 à 4, 6 et 8, mais pour les noms 5,7 ou 9 il recopie le nom dans les 5 et 7 si noms 9 modifiés, ou 7 et 9 si le 5, etc...

et encore, la copie fonctionne.
mais j'ai essayé en mode console, et là ça crash avec strcpy, strncpy, sprintf ...

où est ma bévue ? faut-il s'y prendre comme ça ?
je doute...

merci d'avance, car je suis completement sec

18 réponses

Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Non tu as raison, ca c'est correct:

char *names[]={

"NOM JOUEUR 1",

"NOM JOUEUR 2",

"............................",

etc... il y a 10 noms

};


Tu initialises sur la meme ligne, donc le pointeur est alloué
localement automatiquement. Donc pas besoin ni de malloc ou de new.
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

pour bin ça fonctionne bien mieux avec un struct ;)

struct {
char name[size];
unsigned long score;
} player;
player toptenplayers[nmaxplayer];

et maintenant quand je fais un strncpy(toptenplayers[5].name,buffer,size), ça marche

pfiu (je crois que c'est le *names[] qui pose probleme)
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

#define NAMES_COUNT 10 // exemple => max. de 10 noms
#define NAMES_MAX_LENGTH 32 // exemple => max. de 31 caractères par nom plus le \0 final

dans ton code, chaque élément de « names » est un char*, tu ne peux rien copier là a moins d'allouer de la mémoire ...
sinon, fixe les tailles ::  char names[NAMES_COUNT][NAMES_MAX_LENGTH] = {..., ..., ...}; // <= tu peux faire des strcpy() là
ou encore: char* names[NAMES_COUNT];  names[0] = strdup("un nom ici"); etc. // ici aussi, tu peux faire des strcpy()/etc.

// ton code
char *names[]={
"NOM JOUEUR 1", // names[0] == char* => une adresse => pointe sur "NOM JOUEUR 1" <= tu peux pas écrire là
"NOM JOUEUR 2", // idem pour tous les autres éléments
"............................",
//etc... il y a 10 noms
};

avec ton code, tu aurais dû déclarer « names » de cette facon:
const char* names[] = { // <= « const » car oui, c'est constant, chaque élément pointe sur un « const char* »
"nom 1",
"nom 2",
"nom 3",
// etc.
};

// ceci est bon
char names[NAMES_COUNT][NAMES_MAX_LENGTH];

strcpy(names[0], "nom 1");
strcpy(names[1], "nom 2");
// etc.

// chaque élément est un « tableau » de NAMES_MAX_LENGTH caractère(s), comme si tu avais plusieurs ::
char nom1[NAMES_MAX_LENGTH];
char nom2[NAMES_MAX_LENGTH];
char nom3[NAMES_MAX_LENGTH];
// etc..

le mieux dans ton cas serait probablement un array de taille fixe mais si tu y tiens, dynamic => avec malloc()
en passant, oui tu as raison, on peut très bien faire « char* ptr "une chaine"; » mais le pointeur « ptr » va pointer sur une zone static/constante, "une chaine" const char*, on peut pas écrire là, donc il serait plus adapté d'écrire « const char* ptr = "une chaine"; », c'est ce que tu faisais dans ton code, t'utilisais des pointeurs pointants sur des zones en read-only(const char*) ...

~(.:: NitRic ::.)~
Messages postés
746
Date d'inscription
vendredi 17 juin 2005
Statut
Membre
Dernière intervention
23 mai 2007
9
Il ne faut pas oublier d'allouer la mémoire avant de copier quelque chose dedans :

names[0] = new char[TAILLE_NOM_MAX];
strcpy(names[0], "Chaine à copier");

<hr size="2" width="100%" />Sachant qu'on peut toujours enlever une ligne à un programme, et que dans un programme il y a toujours un bug, un programme peut se résumer à une ligne avec un bug.
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

euh...oui mais je crée pas un nouvel élément, il existe déjà, non ??
ôtez moi d'un doute
j'ai :
char *names[]={
"TEXTE",
"TEXTE"
};
names[0]="TEXTE" . quand je l'affiche il existe bien !? non ?
en plus la taille reste la meme
(en C, "new" ça marche ?? moi non)
Messages postés
746
Date d'inscription
vendredi 17 juin 2005
Statut
Membre
Dernière intervention
23 mai 2007
9
Tu utilise malloc en C. La, pour le moment, ton strcpy essaie de placer des caractères à une zone mémoire inaccessible, car non initialisée.

D'ailleurs, il est déconseillé d'utiliser names[0] = "BLABLA"; Je ne suis même pas sur que ça marche...

<hr size="2" width="100%" />Sachant qu'on peut toujours enlever une ligne à un programme, et que dans un programme il y a toujours un bug, un programme peut se résumer à une ligne avec un bug.
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

en en tête de programme j'ai
char*names[]={"TEXTE","TEXTE"};
ça ne marche pas??? pourtant tout s'affiche et meme se sauvegarde

je precise que je ne fais pas names[0]="texte" dans le programme lui meme

alors là, je cromprends plus rien...
pourtant quand je relis mon bouquin de C, il est bien indiqué dans les déclarations que l'on peut faire char chaine="texte"; comme on fait int valeur=10;
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

bon, avec malloc ça marche, mais j'en suis tout retourné...
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

ha! hmmm...
donc j'en reviens à ma premiere question avec mon principal probleme : comment ecrire dans un tel tableau de char
j'explique : c'est un tableau de nom pour un hiscore
on saisie le nom (taille pre determinée) dans un buffer (char buffer[taille])
et je veux copier ce buffer dans la table de nom à la position N donc dans names[N] :
strncpy(names[N],buffer,taille);

c'est pas que ça marche pas, mais il y a un drôle de bug qui n'apparait pas pour toutes les lignes !
du names[0] à names[4] et 6,8 pas de probleme.
mais quand je fais de meme avec names[5], names[7] ou names[9], alors je me retrouve avec un tableau de nom comme cela :
"TEXTE0"
"TEXTE1"
"TEXTE2"
"TEXTE3"
"TEXTE4"
"SAISIE5" <- ici ce que j'ai copié
"TEXTE6"
"SAISIE5" <- il se recopie ici !!
"TEXTE8"
"SAISIE5" <- et ici !!!

j'hallucine ou bien...
Messages postés
13
Date d'inscription
vendredi 8 septembre 2006
Statut
Membre
Dernière intervention
8 février 2007

si ça marche pas, c'est un bug cqfd ;-)

ton strncpy(names[N],buffer,taille); doit écrire n'imorte où
tu peux essayer un code comme ça

char *names[]={
"NOM JOUEUR 1",
"NOM JOUEUR 2",
"............................",
};
char *pchar=names[1]; //éditer joueur 2
strncpy(pchar,buffer,taille);

au moins il ne pourra pas déborder sur les autres lignes
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

ça bug encore, la meme chose
c'est dingue

je crois que je vais faire autrement, mais comment...
peut etre avec un struct
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
C'est ta déclaration qui n'est pas correct, essais ca:

char *names[]={

{"NOM JOUEUR 1"},

{"NOM JOUEUR 2"},

{"............................"},

etc... il y a 10 noms

};
Messages postés
746
Date d'inscription
vendredi 17 juin 2005
Statut
Membre
Dernière intervention
23 mai 2007
9
Non luhtor, ça ne marchera pas car c'est un tableau a 2 dimensions, et pas 3 (rappelons quand même que une chaine de caractères est un tableau).

<hr size="2" width="100%" />Sachant qu'on peut toujours enlever une ligne à un programme, et que dans un programme il y a toujours un bug, un programme peut se résumer à une ligne avec un bug.
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

en fait, c'est bon maintenant
je n'utilise plus ce type de declaration et ça marche
mais si quelqu'un trouve le pourquoi du comment...
Messages postés
746
Date d'inscription
vendredi 17 juin 2005
Statut
Membre
Dernière intervention
23 mai 2007
9
Ca ne vient pas de la structure, mais du fait que tu déclare ton nom avec un tableau statique (char name[size]), ce qui évite de devoir faire l'allocation dynamique avec malloc. L'allocation statique réserve de la place dans la pile au lieu du tas.

<hr size="2" width="100%" />Sachant qu'on peut toujours enlever une ligne à un programme, et que dans un programme il y a toujours un bug, un programme peut se résumer à une ligne avec un bug.
Messages postés
402
Date d'inscription
mardi 1 mai 2001
Statut
Membre
Dernière intervention
15 août 2011

j'avais pas vu la seconde page, avec une structure c'est parfait, le nom du joueur plus son score

~(.:: NitRic ::.)~
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

he be
merci pour cette explication
je vais voir où j'ai encore mis ce genre de declaration et modifier
Messages postés
92
Date d'inscription
jeudi 24 novembre 2005
Statut
Membre
Dernière intervention
29 mai 2008

et oui, ensuite j'ai trouvé une soluce plus propre avec une structure
mais c'est quand meme bien d'avoir une explication de l'autre solution (en fait je m'en sers sans probleme en read-only la plupart du temps, j'avais pas pensé au write...)