Utilisation de malloc calloc ...

thierclap Messages postés 2 Date d'inscription dimanche 22 novembre 2009 Statut Membre Dernière intervention 27 janvier 2013 - 22 janv. 2013 à 00:12
 ifofana03 - 29 janv. 2013 à 08:58
Bonjour
j'aimerai savoir comment je doit utiliser malloc ou calloc.
en fait sur ce bout de programme :

char adresseip[]={0};//variable pour adresse ip
char fichier[]={0};


int main()
{

    printf("Ecrivez l'adresse ip que vous voulez mettre a chaque debut de     ligne:\n");
    printf("rajouter fin à la suite et appuyer sur entrer\n\n");
    scanf("%15c\n",adresseip);    //lis

    printf("%s\t",adresseip);
    printf("\nAdresseip enregistrer:\n");
    printf("\n");
    printf("Choisissez un fichier à modifier\n");
    scanf("%5c\n",fichier);//recupere le nom du fichier
    printf("%s\n",fichier);//affichage nom de fichier
    printf("");



lorsque j'affiche le nom du fichier , je me rend compte que
j'affiche fin et le debut du nom du fichier...

quelqu'un pourrait il m'aider???

merci d'avance

5 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
22 janv. 2013 à 10:52
Bonjour.

Le souci vient de plusieurs petits détails:
- "char adresseip[]={0};" Lorsque tu ne précises pas la taille d'un tableau, celle-ci est déduite en fonction du nombre d'éléments. Ici, vu que tu as un seul élément, ton tableau aura toujours une taille de 1 (ce qui est évidemment problématique). Il suffit pour corriger cela d'indiquer une taille: "char adresseip[16]={0};" (taille nécessaire + 1 pour le 0 terminal).
- scanf("%15c\n", adresseip) Il ne faut pas mettre de \n dans un scanf. Sinon, scanf ne rendra pas la main avant d'avoir trouvé un saut de ligne supplémentaire. En mettant ceci scanf("%15c", adresseip), tu verras que ça sera bien mieux.

Tu peux utiliser au choix, un tableau fixe ou que tu auras alloué toi même.
Ceci:
  char adresseip[16] = {0};

Pourra aussi être écrit comme ceci:
  char* adressip = malloc(16 * sizeof(char));
  // code
  free(adresseip);



Je te propose une version corrigée de ton code:
#include <stdio.h>

int main(void)
{
  char adresseip[16] = {0};
  char fichier[6] = {0};

  printf("Ecrivez l'adresse ip que vous voulez mettre a chaque debut de ligne:\n"
 "rajouter fin à la suite et appuyer sur entrer\n\n");
  scanf("%15c", adresseip);
  printf("\nAdresseip enregistre: %s\n\n"
 "Choisissez un fichier à modifier\n", adresseip);
  scanf("%5c", fichier);
  printf("%s\n", fichier);

  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
thierclap Messages postés 2 Date d'inscription dimanche 22 novembre 2009 Statut Membre Dernière intervention 27 janvier 2013
27 janv. 2013 à 16:19
il se trouve que si l'utilisateur dépasse le nombre de caractère que peut recevoir adresseip alors j'ai un problème sur la variable fichier.
il reçoit la fin de la premiere entrée et ole debut de la deuxieme entrée......

que dois je faire??
0
Bonjour,
C'est peut-être parce que tu limite le nombre de caractère dans ton scanf a 15 caractères.
"scanf("%15c", adresseip);"
Si tu veux saisir plusieurs caractères utilise le "%s" a la place du "%15c" dans ton scanf, cela t'évitera d'avoir tout le temps a donner le nombre de caractère precis et a avoir des problèmes quand il n'a pas été respectée.
Apres la saisie de l'adresse ip ex: 45:4856:4851:23fin
En tout il y'a 15+3("fin" qui est en plus) caractères.
Si je saisie quelque chose sa ton programme peut fonctionner comme bloqué.
Je m'explique, si tu déclare un tableau de 15 char en memoire les caractères se suivent.
exemple, Imagine que:
"adresseip[0]" soit a l'adresse 1000 et vaut '4' (d'apres la saisie d'en haut)
"adresseip[1]" est a l'adresse 1001 et vaut '5'
"adresseip[2]" est a l'adresse 1002 et vaut ':'
...
"adresseip[14]" est a l'adresse 1014 et vaut '3'
"adresseip[15]" est a l'adresse 1015 et vaut 'f'
"adresseip[16]" est a l'adresse 1016 et vaut 'i'
"adresseip[17]" est a l'adresse 10017 et vaut 'n'

Normalement, il est interdit d'avoir des caractères sur de l'espace non réservé a la déclaration donc avec de la chance il y'a assez d'espace apres le 14 eme caractère et sinon le programme plante parce que les cases memoires sont deja occupé.
Je propose une amelioration du code:
#include <stdio.h>

int main(void)
{
  char adresseip[16]={0};
  char fichier[6] = {0};

  printf("Ecrivez l'adresse ip que vous voulez mettre a chaque debut de ligne:\n"
 "rajouter fin à la suite et appuyer sur entrer\n\n");
  scanf("%s", adresseip);
  adresseip[15]='\0';//Permet d'indiqué de le 14 eme caractère est le dernier
  printf("\nAdresseip enregistre: %s\n\n"
 "Choisissez un fichier à modifier\n", adresseip);
  scanf("%s", fichier);
  printf("%s\n", fichier);

  return 0;
}


Mais si tu ne veut pas d'erreur la methode la plus simple est reserve plus case (exemple 20) et d'utiliser '\0'
1 caractère correspond a un octet donc en memoire ce n'est quasi rien mais si tu aimes utiliser le moins de memoire possible utlise le malloc comme dans le post precedent mais d'encore plus de case et un realloc pour supprimer les cases en trop
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 janv. 2013 à 01:35
@ifofana03: Je ne suis pas du tout d'accord avec les arguments que tu avances.

C'est peut-être parce que tu limite le nombre de caractère dans ton scanf a 15 caractères.

Non, rien à voir.

Si tu veux saisir plusieurs caractères utilise le "%s" a la place du "%15c" dans ton scanf, cela t'évitera d'avoir tout le temps a donner le nombre de caractère precis et a avoir des problèmes quand il n'a pas été respectée.

Il veut précisement 15 caractères, c'est donc une utilisation judicieuse du scanf qu'il a faite. Un %s n'est pas adapté dans son cas.
De plus, mettre un %s, niveau sécurité du code, c'est exactement le contraire ! Le %15c assure que le tableau ne contiendra pas plus de 15 caractères, sécurité que tu n'as pas automatiquement avec un %s...

Apres la saisie de l'adresse ip ex: 45:4856:4851:23fin
En tout il y'a 15+3("fin" qui est en plus) caractères.

Il n'a pas besoin de taper "fin", il ne le faisait que pour remplir le "caractère de bourrage" demandé par un scanf mal écrit (présence d'un \n en trop).

adresseip[15]='\0';//Permet d'indiqué de le 14 eme caractère est le dernier

Dans ton code, cette ligne est inutile. En effet, le tableau a déjà eu toutes ses cases initialisées à 0 (via char adresseip[16]={0};) le dernier caractère contient déjà un 0. On pourrait néanmoins, garder la ligne et ne pas initialiser le tableau (c'est techniquement meilleur). C'est l'un ou l'autre, mais pas les deux. (Ce n'est pas une erreur technique, c'est juste inélégant).

@thierclap:
Le souci vient du fait, qu'après un scanf, si tu as tapé plus de caractères que prévu, ces caractères "dépassent" et sont alors donnés au prochain flux. Il faut se débarrasser de ces caractères superflus. Pour se faire, il existe plusieurs méthodes. Je te propose une fonction "clear" qui utilisent un "getchar" jusqu'à la suppression de tous les caractères indésirables.

#include <stdio.h>

void clear()
{
  char c;
  while ((c = getchar()) != EOF && c != '\n')
    ;
}

int main(void)
{
  char adresseip[16] = {0};
  char fichier[6] = {0};

  printf("Ecrivez l'adresse ip que vous voulez mettre a chaque debut de ligne:\n"
 "rajouter fin à la suite et appuyer sur entrer\n\n");
  scanf("%15c", adresseip);
  clear();

  printf("\nAdresseip enregistre: %s\n\n"
 "Choisissez un fichier à modifier: ", adresseip);

  scanf("%5c", fichier);
  printf("%s\n", fichier);

  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonjour,
J'ai bien commencé mon post avec le mot "peut-être" ce qui signifie que j'avais pas forcement compris le problème qui était de se débarraser des sasie de cette maniere mais bon quand meme tu m'a bien corrigé merci
0
Rejoignez-nous