Language C, "connot convert int to cons char&
Résolu/Fermé
A voir également:
- Language C, "connot convert int to cons char&
- Coco char - Accueil - Réseaux sociaux
- Remplaçant de Coco : quelles solutions pour tchater gratuitement en ligne ? - Accueil - Réseaux sociaux
- Coco chat connexion sur mobile, le tchat est fermé ? ✓ - Forum Réseaux sociaux
- Site coco chat (incitation a payer) ✓ - Forum Vos droits sur internet
- If char ✓ - Forum Programmation
2 réponses
mamiemando
Messages postés
33591
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 mars 2025
7 834
11 avril 2008 à 14:00
11 avril 2008 à 14:00
1) Si tu es en C (et non en C++) il faut utiliser le headers <stdlib.h> et non <cstdlib> (qui wrappe le header C pour le C++). Dans ton cas vu que tu n'utilises ni std::cout, std::cerr, std::cin (et leurs opérateurs << et >>) tu n'as aucune raison d'inclure <iostream> (qui est le header C++ de ces trois flux). En l'occurrence tu utilises printf (qui lui est dans <stdio.h>).
2) Pour la même raison, tu peux virer le using namespace std; qui est spécifique au C++ et qui permet de sous-entendre les std:: (par exemple tu peux écrire cout au lieu de std::cout). Personnellement je déconseille l'utilisation des "using" même si ça entraîne parfois quelques lourdeurs d'écriture.
3) Ensuite il faut éviter l'instruction system qui est une très mauvaise habitude. De plus l'instruction pause n'a de sens que sous windows. En l'occurrence il vaut mieux remplacer system("pause") par :
(ce qui fait exactement la même chose)
4) Apparemment la fonction copy sert à dupliquer une chaîne. Il faut bien voir que cette fonction existe déjà dans la lib C (stcpy) : http://www.manpagez.com/missing.php
Maintenant si c'est un exercice on peut effectivement s'entraîner à coder son propre strcpy.
- Pour commencer quand un entier est positif, on utilise plutôt un unsigned int (ou unsigned en abrégé) car si on se trompe (comparaison entre entier signés et non signés, le compilateur nous préviendra).
- Les fonctions recuperation et copy ne retournent rien donc leur type de retour est void.
- La fonction recuperation ne permet pas de récupérer la chaîne lue !!!
- De plus comme on est en C et pas en C++ les variables doivent être déclarées en début de scope (pour faire simple en début de fonction).
- Ensuite dans copy, une chaîne est un tableau de char donc de type char *.
- Ta fonction copy réécrit la chaîne de départ dans un noueau tableau mais celui-ci n'a pas été alloué. Comme cet espace n'a pas été reservé, le programme plantera et déclenchera une segmentation fault. Il faut donc l'allouer au préalable ou faire un malloc. En terme de design de programme, l'allocation mémoire doit être fait par la fonction qui appelle ta fonction copy. C'est donc ce qu'on va faire.
- La boucle for ne permet pas d'avancer dans la chaîne de départ, tu recopieras donc tout le temps le premier caractère.
Voici le programme corrigé :
Après on peut aller plus loin car ce programme s'écrit beaucoup plus facilement en C++ :
L'avantage c'est que la le programme marche même pour une chaîne de taille supérieure à 10, on n'a pas à se préoccuper des '\0' etc...
Bonne chance
2) Pour la même raison, tu peux virer le using namespace std; qui est spécifique au C++ et qui permet de sous-entendre les std:: (par exemple tu peux écrire cout au lieu de std::cout). Personnellement je déconseille l'utilisation des "using" même si ça entraîne parfois quelques lourdeurs d'écriture.
3) Ensuite il faut éviter l'instruction system qui est une très mauvaise habitude. De plus l'instruction pause n'a de sens que sous windows. En l'occurrence il vaut mieux remplacer system("pause") par :
getchar();
(ce qui fait exactement la même chose)
4) Apparemment la fonction copy sert à dupliquer une chaîne. Il faut bien voir que cette fonction existe déjà dans la lib C (stcpy) : http://www.manpagez.com/missing.php
Maintenant si c'est un exercice on peut effectivement s'entraîner à coder son propre strcpy.
- Pour commencer quand un entier est positif, on utilise plutôt un unsigned int (ou unsigned en abrégé) car si on se trompe (comparaison entre entier signés et non signés, le compilateur nous préviendra).
- Les fonctions recuperation et copy ne retournent rien donc leur type de retour est void.
- La fonction recuperation ne permet pas de récupérer la chaîne lue !!!
- De plus comme on est en C et pas en C++ les variables doivent être déclarées en début de scope (pour faire simple en début de fonction).
- Ensuite dans copy, une chaîne est un tableau de char donc de type char *.
- Ta fonction copy réécrit la chaîne de départ dans un noueau tableau mais celui-ci n'a pas été alloué. Comme cet espace n'a pas été reservé, le programme plantera et déclenchera une segmentation fault. Il faut donc l'allouer au préalable ou faire un malloc. En terme de design de programme, l'allocation mémoire doit être fait par la fonction qui appelle ta fonction copy. C'est donc ce qu'on va faire.
- La boucle for ne permet pas d'avancer dans la chaîne de départ, tu recopieras donc tout le temps le premier caractère.
Voici le programme corrigé :
#include <stdlib.h> #include <stdio.h> #include <string.h> void recuperation(char *phrase){ printf("Entrez votre chaine : "); gets(phrase); printf("la chaine entree est : %s \n", phrase); } void copy (char *phrase,char *copie){ unsigned i; unsigned n = strlen(phrase); for (i=0; i<=n; i++){ // on s'arrete à i==n pour récupérer le '\0' qui termine la chaine copie[i] = phrase[i]; } } int main(){ char phrase[10]; // si la chaîne est de longueur >10, le programme plante char copie[10]; recuperation(phrase); copy(phrase,copie); printf ("la chaine copiee est : %s\n",copie); // system("PAUSE"); getchar(); return EXIT_SUCCESS; }
Après on peut aller plus loin car ce programme s'écrit beaucoup plus facilement en C++ :
#include <iostream> #include <string> #include <cstdio> // getchar() int main(){ std::string phrase; std::cout << "Entrez votre phrase : "; std::cin >> phrase; std::cout << "La phrase entrée est : " << phrase << std::endl; std::string copie = phrase; std::cout << "La phrase copie est : " << copie << std::endl; getchar(); return 0; }
L'avantage c'est que la le programme marche même pour une chaîne de taille supérieure à 10, on n'a pas à se préoccuper des '\0' etc...
Bonne chance
mamiemando
Messages postés
33591
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
20 mars 2025
7 834
12 avril 2008 à 11:47
12 avril 2008 à 11:47
J'ai effectivement fait un projet C++ car les projets C sur mon dev-c++ ont quelques soucis mais je ne connais pas encore le C++. On m'a alors dit que je pouvais procéder ainsi.
Le truc c'est que pour le moment, tu ne tires pas parti des avantages du C++ (cf 2e version que je te propose, beaucoup plus simple) et ton programme ne peut compiler en C. Les indications que je t'ai donné servent simplement à soit tirer pleinement parti des fonctionnalités du C++, soit faire un programme en C pur.
Ma fonction recuperation ne permet pas de récupérer la chaine c'est parce que je dois créer le tableau dans le main? Tu dis que c'est une question de design de l'allouer à l'endroit où on appelle la fonction, est normal que si on l'alloue dans copy ça mette une erreur?
La variable doit effectivement être soit passée en paramètre de la fonction (et crée au niveau du main) soit retournée par la fonction, sans quoi la variable reste locale à la fonction. En terme de design il faut au préalable appréhender la notion de scope (horizon en français) qui est simplement une paire d'accolade (de fonction ou de boucle). En général ce qui est alloué en début de scope doit être désalloué à la fin de ce scope afin de n'oublier personne. Quand tu auras vu les malloc tu verras qu'il faut faire un free, c'est à ca que je fais allusion.
Dans ton cas le scope en question c'est la fonction main, et les instructions sont les appels à tes deux fonctions. Je vais laisser ce point en suspens, on y reviendra ultérieurement si ça t'intéresse. Dis-toi juste pour le moment que tes variables locales sont implicitement désallouées en fin de scope, seuls les pointeurs ont besoin d'être désalloués. Tu verras aussi que cette règle de design ne peut pas toujours être suivie en pratique et c'est pourquoi on a recours à des fonctions "constructeur" (allocation) et "destructeur" (désallocation).
Dans la fonction copy je pensais avoir fait un pointeur me permettant d'avancer dans les caractère après chaque boucle je suppose que je n'ai pas réalisé ce que je pensais avoir fait?
Non ton pointeur n'avance pas dans ce que tu as écrit, seul i était incrémenté dans la boucle for.
Sinon j'aurais eu une question sur, tu écris les fonctions avant le main, c'est préférable ou on peut les écrire après et les déclarer avant comme j'avais fait ou ça ne se fait pas?
Personnellement je mets toujours le main à la fin, ça m'évite de déclarer des prototypes comme tu as fait. Après c'est vraiment comme tu préfères il n'y a pas vraiment de règle.
Je sais je suis un peu curieux mais après tout il faut l'être pour progresser.
C'est plutôt une qualité je trouve
Sinon je vois effectivement mes erreurs et ce qui faut faire pour y remédier, je vais pouvoir avancer dans l'exercice.
Merci encore pour ton aide et ces conseils! ;-)
Pas de soucis, bonne continuation
Le truc c'est que pour le moment, tu ne tires pas parti des avantages du C++ (cf 2e version que je te propose, beaucoup plus simple) et ton programme ne peut compiler en C. Les indications que je t'ai donné servent simplement à soit tirer pleinement parti des fonctionnalités du C++, soit faire un programme en C pur.
Ma fonction recuperation ne permet pas de récupérer la chaine c'est parce que je dois créer le tableau dans le main? Tu dis que c'est une question de design de l'allouer à l'endroit où on appelle la fonction, est normal que si on l'alloue dans copy ça mette une erreur?
La variable doit effectivement être soit passée en paramètre de la fonction (et crée au niveau du main) soit retournée par la fonction, sans quoi la variable reste locale à la fonction. En terme de design il faut au préalable appréhender la notion de scope (horizon en français) qui est simplement une paire d'accolade (de fonction ou de boucle). En général ce qui est alloué en début de scope doit être désalloué à la fin de ce scope afin de n'oublier personne. Quand tu auras vu les malloc tu verras qu'il faut faire un free, c'est à ca que je fais allusion.
{ // debut scope declaration variable + allocation instructions liberer variables allouées } // fin de scope
Dans ton cas le scope en question c'est la fonction main, et les instructions sont les appels à tes deux fonctions. Je vais laisser ce point en suspens, on y reviendra ultérieurement si ça t'intéresse. Dis-toi juste pour le moment que tes variables locales sont implicitement désallouées en fin de scope, seuls les pointeurs ont besoin d'être désalloués. Tu verras aussi que cette règle de design ne peut pas toujours être suivie en pratique et c'est pourquoi on a recours à des fonctions "constructeur" (allocation) et "destructeur" (désallocation).
Dans la fonction copy je pensais avoir fait un pointeur me permettant d'avancer dans les caractère après chaque boucle je suppose que je n'ai pas réalisé ce que je pensais avoir fait?
Non ton pointeur n'avance pas dans ce que tu as écrit, seul i était incrémenté dans la boucle for.
Sinon j'aurais eu une question sur, tu écris les fonctions avant le main, c'est préférable ou on peut les écrire après et les déclarer avant comme j'avais fait ou ça ne se fait pas?
Personnellement je mets toujours le main à la fin, ça m'évite de déclarer des prototypes comme tu as fait. Après c'est vraiment comme tu préfères il n'y a pas vraiment de règle.
Je sais je suis un peu curieux mais après tout il faut l'être pour progresser.
C'est plutôt une qualité je trouve
Sinon je vois effectivement mes erreurs et ce qui faut faire pour y remédier, je vais pouvoir avancer dans l'exercice.
Merci encore pour ton aide et ces conseils! ;-)
Pas de soucis, bonne continuation
Bonsoir,
En vacances depuis ce midi j'ai pu recoder quelques lignes et j'ai encore un léger problème, décidément il est difficile de débuter en C.. ^^
Dans les lignes codées je n'ai pas de soucis à la compilation mais il n'effectue pas ce que je souhaite.
void supprime_espace(char *copie, char *ssespace)
{
unsigned i=0;
unsigned n = strlen(copie);
while (i <= n)
{
if ( !isspace(*copie) )
{
ssespace[i] = copie[i];
i++;
}
else
{
i++;
}
}
}
La nouvelle chaine ssespace qui devrait être la même que la précédente en ayant comme son nom l'indique supprimer les espaces ne le fait pas. j'ai ensuite essayer de passer avec un pointeur voir si ça allait pas mieux fonctionner mais je me suis casser les dents étant donné qu'après m'afficher le même résultat que précédemment le programme plante. Je me demande donc si le problème ne vient pas de la fonction if en fait plutôt mais bon je me suis demander pas mal de choses sans pour autant trouver le résultat escompté.
void supprime_espace(char *copie, char *ssespace)
{
unsigned i=0;
unsigned n = strlen(copie);
char *pcopie = 0;
while (i <= n)
{
if ( !isspace(*pcopie) )
{
ssespace[i] = *pcopie;
pcopie++;
i++;
}
else
{
pcopie++;
i++;
}
}
}
En vacances depuis ce midi j'ai pu recoder quelques lignes et j'ai encore un léger problème, décidément il est difficile de débuter en C.. ^^
Dans les lignes codées je n'ai pas de soucis à la compilation mais il n'effectue pas ce que je souhaite.
void supprime_espace(char *copie, char *ssespace)
{
unsigned i=0;
unsigned n = strlen(copie);
while (i <= n)
{
if ( !isspace(*copie) )
{
ssespace[i] = copie[i];
i++;
}
else
{
i++;
}
}
}
La nouvelle chaine ssespace qui devrait être la même que la précédente en ayant comme son nom l'indique supprimer les espaces ne le fait pas. j'ai ensuite essayer de passer avec un pointeur voir si ça allait pas mieux fonctionner mais je me suis casser les dents étant donné qu'après m'afficher le même résultat que précédemment le programme plante. Je me demande donc si le problème ne vient pas de la fonction if en fait plutôt mais bon je me suis demander pas mal de choses sans pour autant trouver le résultat escompté.
void supprime_espace(char *copie, char *ssespace)
{
unsigned i=0;
unsigned n = strlen(copie);
char *pcopie = 0;
while (i <= n)
{
if ( !isspace(*pcopie) )
{
ssespace[i] = *pcopie;
pcopie++;
i++;
}
else
{
pcopie++;
i++;
}
}
}
11 avril 2008 à 17:19
Ma fonction recuperation ne permet pas de récupérer la chaine c'est parce que je dois créer le tableau dans le main? Tu dis que c'est une question de design de l'allouer à l'endroit où on appelle la fonction, est normal que si on l'alloue dans copy ça mette une erreur?
Dans la fonction copy je pensais avoir fait un pointeur me permettant d'avancer dans les caractère après chaque boucle je suppose que je n'ai pas réalisé ce que je pensais avoir fait?
Sinon j'aurais eu une question sur, tu écris les fonctions avant le main, c'est préférable ou on peut les écrire après et les déclarer avant comme j'avais fait ou ça ne se fait pas?
Je sais je suis un peu curieux mais après tout il faut l'être pour progresser.
Sinon je vois effectivement mes erreurs et ce qui faut faire pour y remédier, je vais pouvoir avancer dans l'exercice.
Merci encore pour ton aide et ces conseils! ;-)