IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Problème realloc char**


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut Problème realloc char**
    Bonjour,

    je suis entrain de faire un petit programme permettant de lire dans un fichier et de récupérer les caractères mot à mot.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    )
    int main()
    {
    	FILE* monFichier = NULL;
    	char *temp;
    	char** tab;
    	int i=0;
    	int j = 0;
    	int taille = 0;
     
    	tab = (char**)malloc(sizeof(char*));
    	tab[0] = (char*)malloc(sizeof(char));
     
    	monFichier = fopen("C:\\Users\\Julien\\Desktop\\test.txt","r");
     
    	if (monFichier != NULL)
        {
    		while(!feof(monFichier))
    		{
    			temp = LireMot(monFichier);
    			taille = strlen(temp);
    			tab[i] = (char*)realloc(tab, taille*sizeof(char));
    			//tab[i] = temp;
     
    			i++;
    			tab = (char**)realloc(tab, i*sizeof(char*));
    		}
            // On peut lire et écrire dans le fichier
        }
        else
    		printf("Impossible d'ouvrir le fichier");
     
    }
    J'essai de faire ca de facon dynamique, et lorsque je récupère un nouveau mot dans la variable temp et que je souhaite réallouer mon tableau, je perds ce qui a dans temp

    J'attends votre aide avec impatience. Merci

  2. #2
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    Bonjour,

    Premièrement, on ne sait pas comment ta fonction LireMot fonctionne, ce qu'elle retourne etc.. Tu pourrais allouer ton temp directement en faisant plutôt lireMot(temp) ou lireMot(&temp) et allouer l'espace pour temp dans ta fonction.

    Ensuite pour copier deux chaînes il vaut mieux utiliser la fonction strcpy en allouant l'espace nécessaire avant comme tu fais (et pas besoin de realloc juste un malloc ou un calloc suffit sur ton tab[i]). Avec le +1 à la fin pour le caractère '\0'
    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    taille = strlen(temp);
    tab[i] = (char*)realloc(tab, (taille*sizeof(char)) + 1);
    strcpy(tab[i],temp);
    Enfin je ferai une reallocation de tab, une incrémentation de i avant de faire la copie de tab[i] : c'est plus propre et tu ne perds pas d'espace.

    Bon ceci est basé sur mes vieux souvenirs de C. Je me trompe peut être ou bien je n'ai pas saisi ton problème (et je n'ai pas testé non plus )mais j'espère que cela t'aideras.

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Ok merci pour tes réponses, je vais travailler dans ton sens.

    Pour la fonction LireMot, je ne peux pas la changer elle doit rester comme elle est déclarée.

    Voici son code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char *LireMot(FILE *_monFichier)
    {
    	char* _buffer;
    	char _temp[50];
     
    	fscanf(_monFichier, "%s",_temp);
    	_buffer = (char*)malloc(strlen(_temp) * sizeof(char));
    	_buffer = _temp;
     
    	return _buffer;
    }

  4. #4
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Les cast sur les malloc sont inutiles ...
    Je ne comprend pas pourquoi tu crées ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tab = (char**)malloc(sizeof(char*));
    tab[0] = (char*)malloc(sizeof(char));
    Là tu crées un 'tableau 2D' de 1 pointeur sur 1 char
    En gros c'est comme si tu faisais : char tab[1][1].
    Et donc tu ne peux pas récupérer ce que retourne ta fonction correctement

    A ce niveau là c'est incorrect :
    Tu alloues de la mémoire dans _buffer et quand tu fais la ligne du dessus, tu fais pointer _buffer sur un autre endroit ...
    De plus comme la variable _temp est une variable locale quand tu retournera _buffer hé bien ce ne sera pas correct

    Il y a sûrement d'autres erreurs ...

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Comme il y a plusieurs mots de plusieurs caractères dans mon fichier, il me faut bien un tableau 2D.

    Ensuite pour les mallocs, si je ne les cast pas de la sorte, j'ai une erreur lorsque je compile.

    Pour ce qui est du retour de buffer, je suis d'accord avec toi, a mon avis il doit y avoir la perte d'info ici.

    J'ai fait les corrections soumises plus hautes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    int main()
    {
    	FILE* monFichier = NULL;
    	char *temp;
    	char** tab;
    	int i=0;
    	int j = 0;
    	int taille = 0;
     
    	tab = (char**)malloc(sizeof(char*));
     
    	monFichier = fopen("C:\\Users\\Julien\\Desktop\\test.txt","r");
     
    	if (monFichier != NULL)
        {
    		while(!feof(monFichier))
    		{
    			temp = LireMot(monFichier);
    			taille = strlen(temp);
    			tab[i] = (char*)malloc(taille*sizeof(char));
    			strcpy(tab[i],temp);
     
    			i++;
    			tab = (char**)realloc(tab, i*sizeof(char*));
    		}
        }
        else
    		printf("Impossible d'ouvrir le fichier");
     
    }

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Apparemment l'erreur venait de

    J'ai remplacé tout ca par un strcpy et ca a l'air de fonctionner

  7. #7
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Citation Envoyé par orj30754 Voir le message
    Ensuite pour les mallocs, si je ne les cast pas de la sorte, j'ai une erreur lorsque je compile.
    Et si tu compiles en C, et non en C++ ça fonctionne ?

    Par contre, il ne fallait pas allouer la 2ème dimension pour ton tableau
    Mais tu n'alloues qu'une seule case, et donc si tu as plusieurs lignes dans ton fichier ça donne quoi ?

  8. #8
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    int main()
    {
    	FILE* monFichier = NULL;
    	char *temp;
    	char** tab;
    	int i=0;
    	int j = 0;
    	int taille = 0;
     
    	tab = (char**)malloc(sizeof(char*));
     
    	monFichier = fopen("C:\\Users\\Julien\\Desktop\\test.txt","r");
     
    	if (monFichier != NULL)
        {
    		while(!feof(monFichier))
    		{
    			temp = LireMot(monFichier);
    			taille = strlen(temp);
    			tab[i] = (char*)malloc(taille*sizeof(char)+1);
    			strcpy(tab[i],temp);
    			i++;
    			tab = (char**)realloc(tab, i*sizeof(char*));
    		}
        }
        else
    		printf("Impossible d'ouvrir le fichier");
     
    	for(j = 0; j< i; j++)
    		printf("%s", tab[j]);
     
    	system("pause");
    }
    voila ma fonction apres remaniement.

    J'ai enlever l'allocation de la deuxième dimension du début car elle ne servait a rien.
    Donc je récupère bien les différents mots, par contre lorsque que j'arrive au printf, afin de voir ce que j'ai récupérer, ca plante.

    A priori ca viendrait du de ma variable i que j'incrémente a chaque mot trouvé, qui dans la boucle d'affichage du printf change de valeur.
    Elle vaut 6 (car 6 mots dans mon texte) et d'un coup passe a 2147483646
    Je comprends pas pourquoi d'un coup elle change de valeur, elle est utilisée nul par ailleurs. Du coup le printf essai d'accéder a des valeurs de mon tableau qui existe pas et ca plante...

  9. #9
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab = (char**)malloc(sizeof(char*));
    Tu n'alloues qu'une seule case ... (déjà dis plus haut)

  10. #10
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Au départ oui, pour le premier mot, mais ensuite dans le While, je realloue mon tableau d'une case en plus à chaque mot trouvé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab = (char**)realloc(tab, i*sizeof(char*));
    Au second tour mon tableau vaudra 2, puis 3 au 3eme etc...

  11. #11
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    A tester mais comme cela est-ce que tu as encore une erreur ? (A tester aussi si tu as plusieurs lignes etc. dans ton fichier)

    1) En fait tab est mis à NULL au début.
    2) on realloue tab avec i*sizeof(char *) mais en ajoutant 1 (car i vaut 0 au début)
    3) on alloue à la position i dans tab la place pour le mot
    4) on copie le mot
    5) enfin on incrémente i

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    	tab = NULL;
    	if (monFichier != NULL)
        {
    		while(!feof(monFichier))
    		{
    			temp = LireMot(monFichier);
    			taille = strlen(temp);
    			tab = (char**)realloc(tab, i*sizeof(char*) + 1);
    			tab[i] = (char*)malloc(taille*sizeof(char)+1);
    			strcpy(tab[i],temp);
    			i++;
     
    		}
        }

  12. #12
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Beniou :
    Petite erreur dans ton code :

    tab = (char**)realloc(tab, (i+1)*sizeof(char*) );

    orj30754 :
    La gestion de i est incorrecte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	int i=0;
    ....
    		while(!feof(monFichier))
    		{
    ....
    			tab[i] = (char*)malloc(taille*sizeof(char)+1);
    			strcpy(tab[i],temp);
    			i++;
    			tab = (char**)realloc(tab, i*sizeof(char*));
    		}
    La réallocation de tab est de i pointeurs, donc le tableau tab doit être indexé de 0 à i-1.
    Or, quand on repart au début de la boucle while on fera tab[i] = .... et on écrit en dehors du tableau tab alloué !

  13. #13
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    Effectivement Diogène, autant pour moi pour cette erreur grossière (je n'avais pas eu le temps de tester) : c'est ce que je voulais faire.
    Merci pour la correction.

  14. #14
    Membre confirmé
    Inscrit en
    Mai 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 98
    Par défaut
    Merci les gars, j'avais aussi corrigé le problème avec le i. Ca marche nikel maintenant.

    Autre chose a part est ce qu'il y a une fonction qui met les caractères en minuscule. J'essai tolower en la castant de toute part mais ca ne marche pas.

  15. #15
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Autre chose a part est ce qu'il y a une fonction qui met les caractères en minuscule. J'essai tolower en la castant de toute part mais ca ne marche pas.
    Vu que tolower() est fait pour ça, il faudrait que tu montres un exemple de ce que tu fais et qui ne marche pas.

  16. #16
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    Pour convertir en minuscule
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i;
    char phrase[20] = "PHRASE EN MAJUSCULE";
    for (i = 0; i < strlen(phrase); i++){
      phrase[i] = tolower(phrase[i]);
    }
    ca devrait fonctionner. Mais bon on n'est pas à l'abris d'erreur d'étourderies aujourd'hui avec moi

  17. #17
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Et pourquoi ça ne marche pas ?
    Qu'est-ce que tu obtiens ?

    PS : Si tu espères obtenir "phrase en minuscule", c'est normal que tu sois déçu

  18. #18
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    J'ai pensé exactement à la même chose que toi Diogène lorsque j'ai initialisé ma variable

Discussions similaires

  1. Problème avec char
    Par choupinette116 dans le forum Débuter
    Réponses: 7
    Dernier message: 23/04/2008, 10h30
  2. Problème Cast char* en std::string
    Par inovah dans le forum SL & STL
    Réponses: 1
    Dernier message: 30/10/2007, 16h32
  3. Classe clavier problème avec char
    Par benjiprog dans le forum Langage
    Réponses: 30
    Dernier message: 30/06/2006, 16h04
  4. pb realloc char**
    Par le mage tophinus dans le forum C
    Réponses: 15
    Dernier message: 10/05/2006, 17h20
  5. [C#] Problème de char[]
    Par GlorfindelHebril dans le forum Windows Forms
    Réponses: 11
    Dernier message: 01/04/2005, 14h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo