Probleme avec un petit prog C
tapharule
-
fiddy Messages postés 11069 Date d'inscription Statut Contributeur Dernière intervention -
fiddy Messages postés 11069 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour, j ai un probleme dans mon prog qui est sence me mettre les mots d une phrase dans un char **
o moment dafficher si la chaine est trop longue jai des caractaire bizar qui apparaissent
et le + bizar c que ci je change la valeur du malloc j obtien dautre ecriture encore
voici mon code source
#include <stdio.h>
#include <stdlib.h>
//char *malloc(int size);
/*
fonction qui compte les mots d une string
*/
int cpt_word(char *str)
{
int i;
int cpt;
char car_prec;
i = 0;
cpt = 0;
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
cpt++;
}
car_prec = str[i];
i++;
}
return (cpt);
}
/*
chaine qui prend la position d une str et sauvegarde la chaine depuis la position jusqu a la rencontre d un espace
*/
char *copy(char *str, char *dest, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
dest[i] = str[debut];
debut++;
i++;
}
dest[i] = '\0';
return (dest);
}
/*
** chaine qui compte le nombre de lettre d un mot (utiliser pour faire un malloc)
*/
int cpt_letter(char *str, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
debut++;
i++;
}
return (i);
}
/*
** fonction general qui met chaque mots dans le char **
*/
char **my_str_to_wordtab(char *str)
{
int i;
int j;
char car_prec;
char **tab;
i = j = 0;
tab = malloc((cpt_word(str) + 1) * sizeof(**tab));
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
tab[j] = malloc((cpt_letter(str, i) + 25) * sizeof(*tab));
copy(str, tab[j], i);
j++;
}
car_prec = str[i];
i++;
}
tab[j] = '\0';
return (tab);
}
/*
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
i++;
}
}
*/
o moment dafficher si la chaine est trop longue jai des caractaire bizar qui apparaissent
et le + bizar c que ci je change la valeur du malloc j obtien dautre ecriture encore
voici mon code source
#include <stdio.h>
#include <stdlib.h>
//char *malloc(int size);
/*
fonction qui compte les mots d une string
*/
int cpt_word(char *str)
{
int i;
int cpt;
char car_prec;
i = 0;
cpt = 0;
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
cpt++;
}
car_prec = str[i];
i++;
}
return (cpt);
}
/*
chaine qui prend la position d une str et sauvegarde la chaine depuis la position jusqu a la rencontre d un espace
*/
char *copy(char *str, char *dest, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
dest[i] = str[debut];
debut++;
i++;
}
dest[i] = '\0';
return (dest);
}
/*
** chaine qui compte le nombre de lettre d un mot (utiliser pour faire un malloc)
*/
int cpt_letter(char *str, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
debut++;
i++;
}
return (i);
}
/*
** fonction general qui met chaque mots dans le char **
*/
char **my_str_to_wordtab(char *str)
{
int i;
int j;
char car_prec;
char **tab;
i = j = 0;
tab = malloc((cpt_word(str) + 1) * sizeof(**tab));
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
tab[j] = malloc((cpt_letter(str, i) + 25) * sizeof(*tab));
copy(str, tab[j], i);
j++;
}
car_prec = str[i];
i++;
}
tab[j] = '\0';
return (tab);
}
/*
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
i++;
}
}
*/
A voir également:
- Probleme avec un petit prog C
- Trier du plus petit au plus grand excel - Guide
- Petit 3 ✓ - Forum Word
- Petit 2 ✓ - Forum Windows
- Petit 9 - Forum Mail
- Comment imprimer une photo en petit ✓ - Forum Photo numérique
7 réponses
pour le main
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("%s\n", tab[i]);
i++;
}
}
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("%s\n", tab[i]);
i++;
}
}
./a.out "a b c d e f g h i j k l m n o p q r s t u v w x y z"
���
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
compren po les ???
���
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
compren po les ???
Salut,
T'as le droit d'utiliser des fonctions déjà existantes ou tout refaire à la main ?
Ton but, c'est de mettre dans un tableau 2D tout ce qui passe en arguments c'est ça ?
Je te propose le code suivant :
T'as le droit d'utiliser des fonctions déjà existantes ou tout refaire à la main ?
Ton but, c'est de mettre dans un tableau 2D tout ce qui passe en arguments c'est ça ?
Je te propose le code suivant :
#include <stdio.h> #include <stdlib.h> #include <string.h> char** my_str_wordtab(const size_t sz,char**argv){ char **tab; tab=malloc(sz*sizeof *tab); if(tab==NULL){ fputs("erreur allocation",stderr); exit(1); } for(int i=0;i<sz;i++){ int taille=strlen(argv[i+1]); tab[i]=malloc((taille+1)*sizeof **tab); if(tab[i]==NULL){ fputs("erreur allocation",stderr); exit(1); } strncpy(tab[i],argv[i+1],taille+1); } return tab; } void desallocation(const int sz, char **tab){ for(int i=0;i<sz;i++){ free(tab[i]);tab[i]=NULL; } free(tab);tab=NULL; } int main(int argc, char **argv){ char **tab; if(argc>1){ tab=my_str_wordtab(argc-1,argv); for(int i=0;i<argc-1;i++) puts(tab[i]); desallocation(argc-1,tab); } return 0; }
merci pour ta reponse . non je ne peux utiliser les fonctions du systeme sinon mon exo etait le suivant
)Écrire une fonction qui decoupe une chaine de caracteres en mots.
La fonction renvoie un tableau, où chaque case contient l'adresse
d'une chaine de caractere representant un mot. Le dernier element
du tableau devra etre egal a 0 pour marquer la fin du tableau.
La chaine qui sera transmise sera modifiable (et modifiee).
La fonction devra être prototypée de la maniére suivante :
char **my_str_to_wordtab(char *str);
or toi ton programme il ne fait que mettre dans ton tab[0] les argument passe en parametre donc meme pas dinteret de cree un char **; vu que yora jamais rien dans tab[1]
donc tu vois normalement si apres avoir compiler jexecute ./a.out "je suis null"
je suis cense avoir dans tab[0] = "je"
dans tab[1] = "suis"
et dans tab[2] = "null"
or dans ton code si j execute ./a.out "je suis null"
jorais dans tab[0] = "je suis null"
sinon jai pu resoudre le probleme dans mon code ct juste un blem sur lallocation o lieu de faire sizeof(*tab)
je faisais sizeof(**tab) et la ou jen mete deux etoile il fallai en mettre qu une seule du coup o lieu de multiplier par 4byte je multiplier par 1bite
Merci davoir utiliser de ton temps pour m aider
)Écrire une fonction qui decoupe une chaine de caracteres en mots.
La fonction renvoie un tableau, où chaque case contient l'adresse
d'une chaine de caractere representant un mot. Le dernier element
du tableau devra etre egal a 0 pour marquer la fin du tableau.
La chaine qui sera transmise sera modifiable (et modifiee).
La fonction devra être prototypée de la maniére suivante :
char **my_str_to_wordtab(char *str);
or toi ton programme il ne fait que mettre dans ton tab[0] les argument passe en parametre donc meme pas dinteret de cree un char **; vu que yora jamais rien dans tab[1]
donc tu vois normalement si apres avoir compiler jexecute ./a.out "je suis null"
je suis cense avoir dans tab[0] = "je"
dans tab[1] = "suis"
et dans tab[2] = "null"
or dans ton code si j execute ./a.out "je suis null"
jorais dans tab[0] = "je suis null"
sinon jai pu resoudre le probleme dans mon code ct juste un blem sur lallocation o lieu de faire sizeof(*tab)
je faisais sizeof(**tab) et la ou jen mete deux etoile il fallai en mettre qu une seule du coup o lieu de multiplier par 4byte je multiplier par 1bite
Merci davoir utiliser de ton temps pour m aider
voici mon code final ci sa tinteress jai juste effacer une * et encore merci
#include <stdio.h>
#include <stdlib.h>
//char *malloc(int size);
int cpt_word(char *str)
{
int i;
int cpt;
char car_prec;
i = 0;
cpt = 0;
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
cpt++;
}
car_prec = str[i];
i++;
}
return (cpt);
}
char *copy(char *str, char *dest, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
dest[i] = str[debut];
debut++;
i++;
}
dest[i] = '\0';
return (dest);
}
int cpt_letter(char *str, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
debut++;
i++;
}
return (i);
}
char **my_str_to_wordtab(char *str)
{
int i;
int j;
char car_prec;
char **tab;
i = j = 0;
tab = malloc((cpt_word(str) + 1) * sizeof(*tab));
// sizeof(**tab) CT LA MON ERREUR
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
tab[j] = malloc((cpt_letter(str, i) + 1) * sizeof(**tab)); // ICI JALLOUE* 4*trop de memoire ca je faisai sizeof(*tab)
copy(str, tab[j], i);
j++;
}
car_prec = str[i];
i++;
}
tab[j] = '\0';
return (tab);
}
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("%s\n", tab[i]);
i++;
}
}
#include <stdio.h>
#include <stdlib.h>
//char *malloc(int size);
int cpt_word(char *str)
{
int i;
int cpt;
char car_prec;
i = 0;
cpt = 0;
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
cpt++;
}
car_prec = str[i];
i++;
}
return (cpt);
}
char *copy(char *str, char *dest, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
dest[i] = str[debut];
debut++;
i++;
}
dest[i] = '\0';
return (dest);
}
int cpt_letter(char *str, int debut)
{
int i;
i = 0;
while ((str[debut] != ' ') && (str[debut] != '\0'))
{
debut++;
i++;
}
return (i);
}
char **my_str_to_wordtab(char *str)
{
int i;
int j;
char car_prec;
char **tab;
i = j = 0;
tab = malloc((cpt_word(str) + 1) * sizeof(*tab));
// sizeof(**tab) CT LA MON ERREUR
car_prec = ' ';
while (str[i] != '\0')
{
if ((car_prec == ' ') && (str[i] != ' '))
{
tab[j] = malloc((cpt_letter(str, i) + 1) * sizeof(**tab)); // ICI JALLOUE* 4*trop de memoire ca je faisai sizeof(*tab)
copy(str, tab[j], i);
j++;
}
car_prec = str[i];
i++;
}
tab[j] = '\0';
return (tab);
}
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("%s\n", tab[i]);
i++;
}
}
Sauf que je n'avais pas l'énoncé, donc pas évident d'aider.
or toi ton programme il ne fait que mettre dans ton tab[0] les argument passe en parametre donc meme pas dinteret de cree un char **
Non tu as dû mal lire mon programme.
Il créé un tableau de pointeurs dont le pointeur i pointera vers des zones du heap alloués avec l'argument argv[i+1].
La preuve est que que dans le main(), j'affiche la valeur du tableau tab[i]. tab[0] contient seulement le premier argument comme tu le souhaitais.
De plus dans ton programme, tu oublies de désallouer les zones du heap avec free, ce qui conduit à des fuites mémoires.
Dans ton main(), tu oublies de faire un return 0;.
Et puis tout simplement ton programme ne marche pas.
Si tu demandes d'afficher tab[1] explicitement lorsque tu enverras deux arguments, ton programme fera un joli segfault, et c'est normal puisque ton algorithme est faux.
Tu mets : while (str[i] != '\0')
Donc à la fin du premier argument (qui contient un \0 pour désigner la fin de la mémoire), t'arrêtes la boucle.
Ce n'est pas seulement le dernier argument qui contient le \0. Si l'espace permet de séparer les arguments au lancement du programme, dans la mémoire ce n'est pas traité de la même façon. Les espaces n'existent plus.
Cdlt
or toi ton programme il ne fait que mettre dans ton tab[0] les argument passe en parametre donc meme pas dinteret de cree un char **
Non tu as dû mal lire mon programme.
Il créé un tableau de pointeurs dont le pointeur i pointera vers des zones du heap alloués avec l'argument argv[i+1].
La preuve est que que dans le main(), j'affiche la valeur du tableau tab[i]. tab[0] contient seulement le premier argument comme tu le souhaitais.
De plus dans ton programme, tu oublies de désallouer les zones du heap avec free, ce qui conduit à des fuites mémoires.
Dans ton main(), tu oublies de faire un return 0;.
Et puis tout simplement ton programme ne marche pas.
Si tu demandes d'afficher tab[1] explicitement lorsque tu enverras deux arguments, ton programme fera un joli segfault, et c'est normal puisque ton algorithme est faux.
Tu mets : while (str[i] != '\0')
Donc à la fin du premier argument (qui contient un \0 pour désigner la fin de la mémoire), t'arrêtes la boucle.
Ce n'est pas seulement le dernier argument qui contient le \0. Si l'espace permet de séparer les arguments au lancement du programme, dans la mémoire ce n'est pas traité de la même façon. Les espaces n'existent plus.
Cdlt
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
si je te dis que ton programme est faux c pas parce que je l ai lu mais car je les tester essaye le main suivant dans ton code
int main(int argc, char **argv)
{
printf("%s", tab[0]);
return (0);
}
il taffichera toute la ligne de commande a coup sur et si tu fait un printf("%s", tab[1]); sa segfault
mais dsl mon programme marche parfaitement si tu reussi a le faire beuguer fait me signe bien sur pour les free je les fait dans mon programme final (c a dire celui que j ai rendu)
Tu mets : while (str[i] != '\0')
Donc à la fin du premier argument (qui contient un \0 pour désigner la fin de la mémoire), t'arrêtes la boucle.
tout a fait c juste le premier argument en ligne de commande qui m intereses d ou argv[1] .
pour tout dire on etait meme pas obliger de prendre les argument en ligne de commande ct juste pour faire different test en ligne de commande mais jorai pu ouvrir mon code mettre dans le main
tab = my_str_to_word_tab("ceci est mon test");
est voir ci j ai les bon resultats en rendant l exo on doit enlever le main c pk jai po fai le test if (argc > 1)
et le return (0);
cordialement
int main(int argc, char **argv)
{
printf("%s", tab[0]);
return (0);
}
il taffichera toute la ligne de commande a coup sur et si tu fait un printf("%s", tab[1]); sa segfault
mais dsl mon programme marche parfaitement si tu reussi a le faire beuguer fait me signe bien sur pour les free je les fait dans mon programme final (c a dire celui que j ai rendu)
Tu mets : while (str[i] != '\0')
Donc à la fin du premier argument (qui contient un \0 pour désigner la fin de la mémoire), t'arrêtes la boucle.
tout a fait c juste le premier argument en ligne de commande qui m intereses d ou argv[1] .
pour tout dire on etait meme pas obliger de prendre les argument en ligne de commande ct juste pour faire different test en ligne de commande mais jorai pu ouvrir mon code mettre dans le main
tab = my_str_to_word_tab("ceci est mon test");
est voir ci j ai les bon resultats en rendant l exo on doit enlever le main c pk jai po fai le test if (argc > 1)
et le return (0);
cordialement
en faite c que tu n as pas bien compris l exo
c juste une fonction qui prend une chaine et te met chacun des mots dans un tableau de chaine
sinon je respecte ceux qui libere la memoire apres allocation . de nos jours les gens passent leur temps a surallouer et ce preocupent tres peu des fuites . ceux qui rend leur prog vulnerables aux hackeurs .
merci
c juste une fonction qui prend une chaine et te met chacun des mots dans un tableau de chaine
sinon je respecte ceux qui libere la memoire apres allocation . de nos jours les gens passent leur temps a surallouer et ce preocupent tres peu des fuites . ceux qui rend leur prog vulnerables aux hackeurs .
merci
Comme je t'ai dit dans mon message 9, ton programme ne met pas chacun des mots dans un tableau puisque si tu demandes l'affichage de la deuxième case, ça segfault.
ce preocupent tres peu des fuites . ceux qui rend leur prog vulnerables aux hackeurs .
Oui, pour le DoS. Mais il y a aussi ceux qui ne fixe pas une taille maximum quand lorsqu'il copie, ce qui peut conduire à récrire sur l'eip au sein du frame de la pile et forcer le retour de la fonction à exécuter une zone dont un pirate aura le contrôle (principe du buffer overflow).
ce preocupent tres peu des fuites . ceux qui rend leur prog vulnerables aux hackeurs .
Oui, pour le DoS. Mais il y a aussi ceux qui ne fixe pas une taille maximum quand lorsqu'il copie, ce qui peut conduire à récrire sur l'eip au sein du frame de la pile et forcer le retour de la fonction à exécuter une zone dont un pirate aura le contrôle (principe du buffer overflow).
mais dsl mon programme marche parfaitement si tu reussi a le faire beuguer fait me signe
D'ac.
Donc, à partir de ton programme, je change juste le main.
Je compile. Et je lance :
Pourtant normalement il aurait dû afficher b, puisque c'est le deuxième argument.
Même chose avec mon programme :
Et si j'affiche tab[0] comme tu me l'as demandé, j'obtiens :
Ce qui est normal puisqu'on demande d'afficher le premier argument (qui est ici a).
D'ac.
Donc, à partir de ton programme, je change juste le main.
int main(int argc, char **argv) { int i; char **tab; tab = my_str_to_wordtab(argv[1]); i = 0; if(argc>2) puts(tab[1]); return 0; }
Je compile. Et je lance :
fiddy@laptop2008:~/bidouille$ ./prg a b Erreur de segmentation (core dumped)
Pourtant normalement il aurait dû afficher b, puisque c'est le deuxième argument.
Même chose avec mon programme :
fiddy@laptop2008:~/bidouille$ ./prg1 a b b
Et si j'affiche tab[0] comme tu me l'as demandé, j'obtiens :
fiddy@laptop2008:~/bidouille$ ./prg1 a b a
Ce qui est normal puisqu'on demande d'afficher le premier argument (qui est ici a).
relie l exo stp
tu tetonne que sa sexfault ?
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
if(argc>2) puts(tab[1]);
return 0;
}
Je compile. Et je lance :
fiddy@laptop2008:~/bidouille$ ./prg a b
Erreur de segmentation (core dumped)
Pourtant normalement il aurait dû afficher b, puisque c'est le deuxième argument.
BEN NON a tab[1] il ne doit y avoir un '\0'
toi tu copy chaque argument passer en parametre dans une case du tableau
c a dire tab[0] = argv[0]
tab[1] = argv[1];
or non c pas se qui est demande pour ce main
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("tab[%d] = %s\n", i, tab[i]);
i++;
}
}
sa maffiche
./a.out "ceci est mon test" noubli po que ./a.out "a" "b" != ./a.out a b
tab[0] = ceci
tab[1] = est
tab[2] = mon
tab[3] = test
or toi pour le meme main
./a.out "ceci est mon test"
tab[0] = ceci est mon test
es ke tu voi un peu quand tu test c juste le first argument qui tinteress pas le reste sa pren en parametre un char *str et nn un char **tab
tu tetonne que sa sexfault ?
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
if(argc>2) puts(tab[1]);
return 0;
}
Je compile. Et je lance :
fiddy@laptop2008:~/bidouille$ ./prg a b
Erreur de segmentation (core dumped)
Pourtant normalement il aurait dû afficher b, puisque c'est le deuxième argument.
BEN NON a tab[1] il ne doit y avoir un '\0'
toi tu copy chaque argument passer en parametre dans une case du tableau
c a dire tab[0] = argv[0]
tab[1] = argv[1];
or non c pas se qui est demande pour ce main
int main(int argc, char **argv)
{
int i;
char **tab;
tab = my_str_to_wordtab(argv[1]);
i = 0;
while (tab[i] != '\0')
{
printf("tab[%d] = %s\n", i, tab[i]);
i++;
}
}
sa maffiche
./a.out "ceci est mon test" noubli po que ./a.out "a" "b" != ./a.out a b
tab[0] = ceci
tab[1] = est
tab[2] = mon
tab[3] = test
or toi pour le meme main
./a.out "ceci est mon test"
tab[0] = ceci est mon test
es ke tu voi un peu quand tu test c juste le first argument qui tinteress pas le reste sa pren en parametre un char *str et nn un char **tab