[C++] char *

char * [C++] - Programmation

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

Reply

Marsh Posté le 19-12-2001 à 13:30:36   

Reply

Marsh Posté le 19-12-2001 à 13:42:55    

tu peux montrer comment t'as déclaré "nom"?

Reply

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


---------------
DEBANNISSEZ BRUNOCREMER ET DBZ ET Sly Angell
Reply

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? :D


---------------
DEBANNISSEZ BRUNOCREMER ET DBZ ET Sly Angell
Reply

Marsh Posté le 19-12-2001 à 15:44:17    

voila comment j'ai declaré :  
class personne
{
   protected :
           char *nom;
           blablabla....
   public :
          blablabla ....
};

Reply

Marsh Posté le 19-12-2001 à 15:45:06    

Des tutorials HTML? Plus tard peut etre!

 

[edtdd]--Message édité par Ace17--[/edtdd]

Reply

Marsh Posté le 19-12-2001 à 15:46:07    

ben tu ferais mieux de déclarer nom de la maniere suivante
 
char nom[64];

Reply

Marsh Posté le 19-12-2001 à 16:23:01    

non je dois absolument garder mon char *
 
comment dois je faire?

Reply

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*.

Reply

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)

Reply

Marsh Posté le 19-12-2001 à 16:32:00   

Reply

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 :
  1. class Personne   
  2. {
  3.   protected :
  4.           char *nom;
  5.   public :
  6.          Personne(int x = 64);
  7.          virtual ~Personne();
  8. };
  9. Personne::Personne(int x) {
  10. // assertions sur x
  11.     nom = new char[x];
  12. }
  13. Personne::~Personne() {
  14.     delete[] nom;
  15. }


 
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.


---------------
Pipiru piru piru pipiru pi
Reply

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...


---------------
Pipiru piru piru pipiru pi
Reply

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 !!  :ouch:

Reply

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

Reply

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)  




 
 
 :non: C'est pas pourrit les char*, y faut juste savoir s'en servir... :pt1cable:  
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 ! :D

 

[edtdd]--Message édité par El_Gringo--[/edtdd]

Reply

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, :sarcastic:


---------------
Pipiru piru piru pipiru pi
Reply

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  :cry:

Reply

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

Reply

Marsh Posté le 19-12-2001 à 17:53:35    

essaie peut etre avec getline() ?

Reply

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


---------------

Reply

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

Reply

Marsh Posté le 19-12-2001 à 18:47:31    

sisicaivrai a écrit a écrit :

essaie peut etre avec getline() ?  




t'as essayé?

Reply

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

Reply

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

Reply

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 ;)

Reply

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


---------------

Reply

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

Reply

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)  




 :lol:  :lol:  :lol:  
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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 20-12-2001 à 00:10:21    

gilou a écrit a écrit :

 
 :lol:  :lol:  :lol:  
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...

Reply

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 !:D
é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 !:D

 

[edtdd]--Message édité par El_Gringo--[/edtdd]

Reply

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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).

Reply

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)

Reply

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 ! :na:

Reply

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

Reply

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 ?

Reply

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

Reply

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 !?)

Reply

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.  
Feature Only in Professional and Enterprise Editions   Static linking to MFC is supported only in Visual C++ Professional and Enterprise Editions. For more information, seeVisual C++ Editions.If you dynamically link your application to the MFC library, you will, at a minimum, need to redistribute MFCx0[U].DLL and MSVCRT.DLL, where x is the version number. MFCx0[U].DLL includes all of the basic framework classes. All MFC DLLs use the shared version of the C run-time library; thus, MSVCRT.DLL is required. If your application uses the MFC database classes, such as CRecordset and CRecordView, you will need to redistribute ODBC and any ODBC drivers that your application uses.


 
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

Reply

Marsh Posté le 20-12-2001 à 12:41:57    

legreg a écrit a écrit :

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.  
Feature Only in Professional and Enterprise Editions   Static linking to MFC is supported only in Visual C++ Professional and Enterprise Editions. For more information, seeVisual C++ Editions.If you dynamically link your application to the MFC library, you will, at a minimum, need to redistribute MFCx0[U].DLL and MSVCRT.DLL, where x is the version number. MFCx0[U].DLL includes all of the basic framework classes. All MFC DLLs use the shared version of the C run-time library; thus, MSVCRT.DLL is required. If your application uses the MFC database classes, such as CRecordset and CRecordView, you will need to redistribute ODBC and any ODBC drivers that your application uses.


 
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  




 
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...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed