char * [C++] - Programmation
Marsh Posté le 19-12-2001 à 13:46:00
Ace17 a écrit a écrit : tu peux montrer comment t'as déclaré "nom"? |
la ta structure sappelle p
et nom est un element de ta structure
Marsh Posté le 19-12-2001 à 13:46:29
Ace17 a écrit a écrit : tu peux montrer comment t'as déclaré "nom"? |
ta pas prévu de faire un guide facile pour le html aussi? et le java?
Marsh Posté le 19-12-2001 à 15:44:17
voila comment j'ai declaré :
class personne
{
protected :
char *nom;
blablabla....
public :
blablabla ....
};
Marsh Posté le 19-12-2001 à 15:45:06
Des tutorials HTML? Plus tard peut etre!
[edtdd]--Message édité par Ace17--[/edtdd]
Marsh Posté le 19-12-2001 à 15:46:07
ben tu ferais mieux de déclarer nom de la maniere suivante
char nom[64];
Marsh Posté le 19-12-2001 à 16:23:01
non je dois absolument garder mon char *
comment dois je faire?
Marsh Posté le 19-12-2001 à 16:30:30
mais tu sais, quand tu fais :
char szNom[64];
szNom est quand même un char*.
Marsh Posté le 19-12-2001 à 16:32:00
les char* c'est tout pourri, il vaut mieux s'en méfier, suit le conseil char nom[TAILLE]; sinon tu risques d'avoir des problèmes d'allocation de mémoire (initialisation de var, etc etc)
Marsh Posté le 19-12-2001 à 16:39:42
Plutot de hardcoder la taille du nom dans la classe et d'utiliser un tableau statique, on peut créer le tableau dans le constructeur, c'est plus propre :
Code :
|
Après tu fais un accesseur du style
Personne::setNom(const char* str) {
// assertions sur str...
strcpy(nom,str); // effectue une copie du nom
}
Le problème de ton "char* nom;" c'est qu'il s'agit juste d'un pointeur, donc si tu copies juste le pointeur dans ta structure (en faisant dans ce cas là "nom = str" ), il y à une hypothèse cachée : le contenu de str doit durer au moins aussi longtemps qu'une instance de Personne. Il faut à tout prix eviter ce genre de problème. En créant et en détruisant la chaine "nom" dans la classe, c'est Personne qui a la responsabilité de son propre nom donc ça reste cohérent.
Si tu considères qu'une personne possède nécessairement un nom, tu le mets direct en paramètre du constructeur, etc... etc...
Le C++ autorise autant de constructeurs que l'ont veut : il faut en profiter !
H.T.H.
Marsh Posté le 19-12-2001 à 16:42:12
sisicaivrai a écrit a écrit : les char* c'est tout pourri, il vaut mieux s'en méfier, suit le conseil char nom[TAILLE]; sinon tu risques d'avoir des problèmes d'allocation de mémoire (initialisation de var, etc etc) |
Qu'est ce qui dit lui ? "char* c'et tout pourri" ???? Porte nawak...
Marsh Posté le 19-12-2001 à 16:44:40
tout à fait d'accord, si tu penses cela tu penses que les pointeurs sont pourris ... po compris l'intéret tu as !!
Marsh Posté le 19-12-2001 à 16:45:50
n0mad a écrit a écrit : Qu'est ce qui dit lui ? "char* c'et tout pourri" ???? Porte nawak... |
utilisé n'importe comment, oui, c tout pourri
Marsh Posté le 19-12-2001 à 16:50:10
sisicaivrai a écrit a écrit : les char* c'est tout pourri, il vaut mieux s'en méfier, suit le conseil char nom[TAILLE]; sinon tu risques d'avoir des problèmes d'allocation de mémoire (initialisation de var, etc etc) |
C'est pas pourrit les char*, y faut juste savoir s'en servir...
quand tu déclare un char*, c juste un pointeur. après, y reste à réserver de l'espace mémoire pour faire pointer le char* dessus, avec un petit malloc (ou un new char(NBCHAR) si t en c++).
après, y suffit de penser à libérer l'espace avec un free (si t'as fait un malloc) ou un delete (si t'as fait un new), et ça devient exactement la même chose qu'un char[]. Sauf qu'ici, c ce qu'on appel de l'allocation dynamique de mémoire, on a donc en plus la possibilité d'agrandir ou réduire l'espace mémoire réservé... bien utile desfois !
EDIT: ha... un peu en retard moi, apparement je suis pas le 1er à lui tomber dessus !
[edtdd]--Message édité par El_Gringo--[/edtdd]
Marsh Posté le 19-12-2001 à 16:51:23
sisicaivrai a écrit a écrit : utilisé n'importe comment, oui, c tout pourri |
Philosophique, la reflexion,
Marsh Posté le 19-12-2001 à 16:53:36
El_Gringo a écrit a écrit : Sauf qu'ici, c ce qu'on appel de l'allocation dynamique de mémoire, on a donc en plus la possibilité d'agrandir ou réduire l'espace mémoire réservé... bien utile desfois ! |
oui, mais pas tellement pour ce qu'il veut faire.
Je signalais simplement qu'il était dangereux de jouer avec des char* sans les initialiser, pas la peine de tous me tomber dessus chuis d'assez mauvaise humeur
Marsh Posté le 19-12-2001 à 17:35:36
voici ce que j'ai fais pour corriger :
{
if (nom) delete [] nom;
nom = new char[strlen(s)+1]; // s est passe en parametre
strcpy(nom,s);
}
est ce que ca vous parait correct?
j'ai aussi une deuxieme question (je passe les details du code):
cout <<"Adresse : ";
cin >> adresse;
cout <<"Code Postal : ";
cin >> cp;
cout <<"Localite : ";
cin >> localite;
si dans adresse je rentre un truc du style "nom_de_la_rue" ca passe, si par contre j'entre "nom_de_la_rue numero", la demande du code postal est "skippée"... ca vient du fait qu'il y a un espace qui a ete encodé a la ligne avant
comment puis je corriger cela?
merci
Marsh Posté le 19-12-2001 à 18:28:16
Slash- a écrit a écrit : voici ce que j'ai fais pour corriger : { if (nom) delete [] nom; nom = new char[strlen(s)+1]; // s est passe en parametre strcpy(nom,s); } est ce que ca vous parait correct? j'ai aussi une deuxieme question (je passe les details du code): cout <<"Adresse : "; cin >> adresse; cout <<"Code Postal : "; cin >> cp; cout <<"Localite : "; cin >> localite; si dans adresse je rentre un truc du style "nom_de_la_rue" ca passe, si par contre j'entre "nom_de_la_rue numero", la demande du code postal est "skippée"... ca vient du fait qu'il y a un espace qui a ete encodé a la ligne avant comment puis je corriger cela? merci |
oui ca vient de l'espace met un _ et c bon
au fait garde ton char* c mieu
et tu met p->nom
Marsh Posté le 19-12-2001 à 18:43:16
ben justement c'est ca le prob,
je veux mettre un espace !
je sais qu'il y a une fonction pour "comprendre" ca mais je ne la connais pas, si quelqu'un la connait, qu'il me dise svp
merci
Marsh Posté le 19-12-2001 à 18:47:31
sisicaivrai a écrit a écrit : essaie peut etre avec getline() ? |
t'as essayé?
Marsh Posté le 19-12-2001 à 18:54:03
non j'ai pas su car je sais pas dans quel header cette fonction est definie, ni quelle parametre elle prend
Marsh Posté le 19-12-2001 à 18:55:52
Slash- a écrit a écrit : non j'ai pas su car je sais pas dans quel header cette fonction est definie, ni quelle parametre elle prend |
jette un oeil là, par exemple : http://www.cplusplus.com/ref/iostr [...] tline.html
Marsh Posté le 19-12-2001 à 19:12:37
ok merci mais ca marche pas,
cette fois ci ce n'est plus "code postal" qui est skippé mais "adresse" lui meme !
ca m'avance pas ca
Marsh Posté le 19-12-2001 à 19:31:43
ah ok j'ai compris ce que tu voulais faire
c pour quoi qu'on te demande ca?
moi j'ai fait la meme chose en c++ avec getch
Marsh Posté le 19-12-2001 à 22:44:04
C'est une applic que je dois faire pour l'ecole (graduat en informatique)
c'est une hierarchie de ce type que je dois faire :
personne
membre personnel client
client station client meteo
Marsh Posté le 19-12-2001 à 23:04:30
sisicaivrai a écrit a écrit : les char* c'est tout pourri, il vaut mieux s'en méfier, suit le conseil char nom[TAILLE]; sinon tu risques d'avoir des problèmes d'allocation de mémoire (initialisation de var, etc etc) |
N'importe quoi.
En fait, c'est les declarations char nom[TAILLE]; qui sont pourries lorsqu'on ne maitrise pas la taille des donnees devant etre stockees par nom (cas d'une valeur recuperee depuis la console par exemple), car qque soit la valeur de taille, il y a toujours un moment ou qque chose de trop grand va vouloir s'y mettre. Les lois de Murphy marchent tres tres bien dans ces cas la:
Si le buffer a une taille fixe, elle sera trop petite.
Si on augmente la taille du buffer, elle sera toujours trop petite.
A+,
Marsh Posté le 20-12-2001 à 00:10:21
gilou a écrit a écrit : N'importe quoi. En fait, c'est les declarations char nom[TAILLE]; qui sont pourries lorsqu'on ne maitrise pas la taille des donnees devant etre stockees par nom (cas d'une valeur recuperee depuis la console par exemple) |
n'empeche si tu fais un char* nom; cin>>nom; après bonne chance pour manipuler nom...
'fin je repete, pour ce que j'en dis...
pour moi une alloc dynamique ne sert que si on tiens absolument a pouvoir mettre des trucs de taille variable
ici je n'en vois pas trop l'interet
enfin je vous trouve bien acide ce soir...
Marsh Posté le 20-12-2001 à 08:45:30
sisicaivrai a écrit a écrit : n'empeche si tu fais un char* nom; cin>>nom; après bonne chance pour manipuler nom... 'fin je repete, pour ce que j'en dis... pour moi une alloc dynamique ne sert que si on tiens absolument a pouvoir mettre des trucs de taille variable ici je n'en vois pas trop l'interet enfin je vous trouve bien acide ce soir... |
ha, bah quand on raconte n'imp, faut s'attendre sur un forum de programmation, faut s'attendre à se prendre des programmeurs sur la gueule !
évidement que char* ça marche pas bien (pas du tout d'ailleur je pense, ou alors 1 fois sur 10)... c mal programmé, c tout !
D'abbord, le C, c'est nul y suffit d'oublier de mettre les ';' à la fin de tes lignes et ça marche plus !
[edtdd]--Message édité par El_Gringo--[/edtdd]
Marsh Posté le 20-12-2001 à 09:39:46
sisicaivrai a écrit a écrit : n'empeche si tu fais un char* nom; cin>>nom; après bonne chance pour manipuler nom... 'fin je repete, pour ce que j'en dis... pour moi une alloc dynamique ne sert que si on tiens absolument a pouvoir mettre des trucs de taille variable ici je n'en vois pas trop l'interet enfin je vous trouve bien acide ce soir... |
L'interet, c'est quand tu ne maitrises pas la taille de ce tu as a y mettre, parce que ce sont des donnees exterieures a ton programme.
A+,
Marsh Posté le 20-12-2001 à 10:56:52
Slash- a écrit a écrit : Salut, voici une partie de mon code: cout <<"Votre nom : "; cin >> p.nom; nom est un char * d'une classe personne (p). On m'a dit que ce n'etait pas la bonne solution de mettre p.nom directement dans le cin, mais on ne m'a pas explique pourquoi ni la solution... quelqu'un peut il m'aider? merci |
Pour faire ca, le mieux c'est d'utiliser la classe string
(std::string). En effet quand tu fais
cin >> p.nom
Le programme va ecrire a l'adresse p.nom ce qu'il a trouve
sur le flux cin. Toi tu dois avoir reserver la place suffisante
en memoire (allocation dynamique). Et si il n'y a pas la place,
ca ecrit n'importe ou !
Avec string tout ca se fait tout seul ! Et la chaine est
detruite quand tu n'en as plus besoin (destruction de la classe)
(#include <string.h> ou #include<string> using namespace std
a rajouter en haut du code).
Marsh Posté le 20-12-2001 à 10:57:51
El_Gringo a écrit a écrit : mais tu sais, quand tu fais : char szNom[64]; szNom est quand même un char*. |
Presque szNom est alors un const char * (on peut pas changer
l'adresse)
Marsh Posté le 20-12-2001 à 11:00:04
bah... un const char* c'est un char* ... qui est constant, mais c un char* !! non mais !
Marsh Posté le 20-12-2001 à 11:08:13
un const char *
c'est un char * qui est const
donc dont tu ne peux pas changer
la valeur. Donc tu as interet
soit a prevoir une taille suffisante
soit etre sur de la validite de
tes donnees. (quand je dis sur
ca veut dire qu'il n'y a pas
de moyen de faire autrement)
Si tu programmes en C++
la maniere la plus propre
c'est effectivement
d'utiliser les string.Point.
Si tu veux faire
sans, tu vas finir par reprogrammer
les strings.
Sauf evidemment si tu SAIS que
tes donnees ne vont pas depasser 32 caracteres
et que tu prends la peine de valider
tes donnees avant de les stocker dans tes
variables.
Sinon donnees non validees => plantages
inexpliques + trou de securite potentiel.
A+
LEGREG
Marsh Posté le 20-12-2001 à 11:16:43
y a une question que je me pose sur les string et autres trucs de la STL:
si on en utilise, y a aucune dll qui est linkée en plus ? (ce qui ferai qu'on est obligé de livrer cette dll avec les appli)
par exemple, pour les MFC, on a MFC42.dll
là y en a réellement aucune ?
Marsh Posté le 20-12-2001 à 11:23:50
c'est pas un probleme lie a la STL
(qui est une librairie de templates)
mais plutot un probleme lie a l'implantation
A ma connaissance l'implantation de la STL de Visual
ne necessite pas de librairie dynamique externe.
(les mfc non plus sauf si tu compiles en dynamic)
A+
LEGREG
Marsh Posté le 20-12-2001 à 11:35:58
ha... soit t'as pas compris ce que je veux dire, sois tu te plante !
Si on fait une appli avec les MFC, on utilise la dll MFC42.dll
une fois que t'as compilé ton truc, tout bien, ton exe à besoin de cette dll pour fonctionner, qu'on l'utilise en dynamique ou en static... logique !
Sur nos postes, les environnements de dev (VC et autres) ont déja installé tout ce qu'y faut. Mais desfois, en arrivant chez les cliens, y a des surprises...
j'voulais savoir ce qu'il en est avec la STL... (string c bien un truc de la STL, non !?)
Marsh Posté le 20-12-2001 à 12:03:58
Tu es encore plus a la rue que moi apparemment
Citation : You can link your application or DLL with the MFC library either statically or dynamically. |
Donc pour la STL comme je disais
ca depend de l'implantation
=> se referer a la doc de l'outil
des fois ca sert.
Les STL n'ont a priori pas
besoin d'une librairie dynamique
externe mais parfois il en faut
tout de meme une a cause
de l'implantation des STL par l'editeur
de la librairie.
A+
LEGREG
Marsh Posté le 20-12-2001 à 12:41:57
legreg a écrit a écrit : Tu es encore plus a la rue que moi apparemment
|
Le bout de texte que tu me met en gras à rien à voir !!?
Ouais, si on met en static, peut être qu'il met là dll dans l'exe... ce qui grossit l'exe d'1 bon Mo, mais évite de se trainer la dll partout...
Marsh Posté le 19-12-2001 à 13:30:36
Salut,
voici une partie de mon code:
cout <<"Votre nom : ";
cin >> p.nom;
nom est un char * d'une classe personne (p). On m'a dit que ce n'etait pas la bonne solution de mettre p.nom directement dans le cin, mais on ne m'a pas explique pourquoi ni la solution...
quelqu'un peut il m'aider?
merci