Calcul longueur chaine [Résolu]

pilou007 - 10 janv. 2017 à 10:33 - Dernière réponse :  pilou007
- 10 janv. 2017 à 23:58
Bonjour,
J'ai un souci pour calculer la longueur d'une chaine, le but c'est de concatener des int, des doubles et des chaines dans une seule chaine pour faire un .csv donc avec des ;...
Voici mon code:
// on réalloue la taille de strTemp. +2 pour le ';'
strTemp = realloc (strTemp, strlen(Tab_Transition_To_Charge_or_To_Discharge) * sizeof(char) +2 );

// Ajout dans la ligne à écrire dans le fichier. 
sprintf(strTemp, "%s;", Tab_Transition_To_Charge_or_To_Discharge);
strcat(ligne, strTemp);

// on réalloue la taille de strTemp
strTemp = realloc (strTemp, sizeof(double) +2 ); // + 2pour un ; et la fin de chaine

// Ajout dans la ligne à écrire dans le fichier
sprintf(strTemp, "%.3f;", getDoubleFromData(Read_EVENT_MEMORY, Determine__Read_EVENT_MEMORY, 4, 4)/1000);

strcat(ligne, strTemp);

La longueur est de 10 octets, mais c'est ce que je veux car si mon double fait; 50.537, c'est bon, mais si mon double fait 104732.256 (et je ne compte pas le ;), je dépasse la taille.
Donc mla question, c'est comment faire?
Si je fait un
strTemp = realloc (strTemp, 20);
ça va fonctionner, mais lorsque je fais mon strcat, il ajoute les 20 char et non pas juste la valeur du double plus un ;.....
Merci pour votre aide
Afficher la suite 

4 réponses

Répondre au sujet
[Dal] 4466 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 29 novembre 2017 Dernière intervention - Modifié par [Dal] le 10/01/2017 à 14:29
0
Utile
Salut,

Puisque tu veux produire un fichier .csv, le plus simple est d'écrire directement dans le fichier (avec
fprintf()
), plutôt qu'en mémoire pour ensuite écrire dans le fichier (ce qui te contraint à gérer l'allocation mémoire).

Si tu as une bonne raison de faire autrement et de stocker d'abord des chaînes en mémoire, il y a plusieurs moyens ou stratégies.

L'une d'elle est d'utiliser
snprintf()
avec un tampon mémoire délibérément insuffisant, pour faire usage de la valeur de retour (plus 1), pour déterminer quel aurait été le nombre de chars écrits si la taille du tampon avait été suffisante, et donc de l'espace mémoire nécessaire.

http://www.cplusplus.com/reference/cstdio/snprintf/

ensuite, tu alloues l'espace nécessaire avec
malloc
et tu fais un
snprintf
sur ce tampon correctement dimensionné

il faut un compilateur C99 implémentant correctement cette fonction pour cela (avec gcc, passer l'option
-std=c99
)

gcc a aussi une extension
asprintf()
, qui alloue la mémoire nécessaire toute seule :

http://man7.org/linux/man-pages/man3/asprintf.3.html

D'autres stratégies consistent à utiliser des tailles supérieures aux tailles maximales pouvant être produites, en fonction des types et des données à formater.


Dal
Commenter la réponse de [Dal]
0
Utile
2
Salut,
Merci pour ta réponse, mais il me semble que ça ne résout pas le problème. En effet, dans
snprintf ( char * s, size_t n, const char * format, ... );

on ne connait toujours pas n
[Dal] 4466 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 29 novembre 2017 Dernière intervention - 10 janv. 2017 à 18:53
tu n'as pas (bien) lu mon post, ni la doc sur snprintf

donc, comme je disais, si n est insuffisant, snprintf retourne le nombre de chars qui auraient été nécessaires pour tout écrire. Comme c'est cette information dont on a besoin, on peut la passer dans un deuxième temps à un second appel à snprintf.

une démo :

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char small[2];  /* espace de stockage trop petit */
    char * st;      /* pointeur vers char pour tampon adapté */

    int un_int = 15872;
    double un_double = 56.37829928;
    char une_chaine[] = "une chaîne";

    int taille = snprintf(small, 1, "%d - %f - %s",
            un_int, un_double, une_chaine);
    printf("La taille nécessaire est : %d\n", taille + 1);

    st = malloc(taille + 1);
    if (st) {
        snprintf(st, taille + 1, "%d - %f - %s",
                un_int, un_double, une_chaine);
        printf("J'ai réussi à allouer %d bytes pour stocker "
                "cette chaîne :\n%s\n", taille + 1, st);
    }
    free(st);

    return 0;
}

donne :
$ gcc -Wall -std=c99 pillou007.c
$ ./a.out
La taille nécessaire est : 32
J'ai réussi à allouer 32 bytes pour stocker cette chaîne :
15872 - 56.378299 - une chaîne

Youpi !

Dal
pilou007 > [Dal] 4466 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 29 novembre 2017 Dernière intervention - 10 janv. 2017 à 23:58
Effectivement, je n'avais pas bien lu, désolé et merci pour ton exemple très parlant...
En fait si j'alloue 30 alors que j'en ai besoin de 20, lors du sprintf, je pense qu'il met le '\0' juste à la fin des car utiles et lors du strcat, il ne prend que les caractères utiles, donc tout va bien, je m'en suis sorti comme ça...
Encore merci.
Bye
Pascal
Commenter la réponse de pilou007