Signaler

Calcul longueur chaine [Résolu]

Posez votre question pilou007 - Dernière réponse le 10 janv. 2017 à 23:58 par pilou007
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 
Utile
+0
moins plus
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
Donnez votre avis
Utile
+0
moins plus
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] 4107Messages postés mercredi 15 septembre 2004Date d'inscription ContributeurStatut 20 janvier 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
Répondre
pilou007- 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
Répondre
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !