<...> et que j'ai besoin ensuite de lui concatener plus de 20 caracteres,
comment je fais ?
<...> et que j'ai besoin ensuite de lui concatener plus de 20 caracteres,
comment je fais ?
<...> et que j'ai besoin ensuite de lui concatener plus de 20 caracteres,
comment je fais ?
Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Bonsoir,
J'ai un petit problème avec strcat/sprintf notamment en C.
En fait je "parse" un char* caractere par caractere, et je concatene ces
caracteres dans une autre chaine (chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je lui mets une
taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20
caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Bonsoir,
J'ai un petit problème avec strcat/sprintf notamment en C.
En fait je "parse" un char* caractere par caractere, et je concatene ces
caracteres dans une autre chaine (chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je lui mets une
taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20
caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Bonsoir,
J'ai un petit problème avec strcat/sprintf notamment en C.
En fait je "parse" un char* caractere par caractere, et je concatene ces
caracteres dans une autre chaine (chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je lui mets une
taille de 20, et que j'ai besoin ensuite de lui concatener plus de 20
caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Exple (append a faire en fonction du parsing):
#include <stdio.h>
char * appendChar(char * s, size_t lng, char c)
{
if (s != NULL)
{
size_t pos = strlen(s);
if (pos < lng-1)
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
int main(void)
{
/* Chaine destination a bien dimensionner, 100 ici (99 car. max) */
char dst_arr[100];
dst_arr[0] = ' ';
/* Les append a faire en fonction du parsing */
/* Traitement a mettre dans une fonction par exemple */
appendChar(dst_arr,100,'a');
appendChar(dst_arr,100,'b');
appendChar(dst_arr,100,'c');
/* etc ...*/
puts(dst_arr);
return 0;
}La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Voir realloc().
C'est une solution, mais que je préfère réallouer des blocs conséquents,
je ne m'amuserais pas a utiliser une telle solution pour rajouter un
caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change
pas (peut etre tronque si taille demandée plus petite)), tu gardes le
bloc précédemment alloué, soit l'agrandissement marche, soit il ne
marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Exple :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char * dst_s, * dst_s_sav;
char * part1_s = "Il y a une ";
char * part2_s = "greve a l'aeroport de Brest et ca m'emmerde beaucoup";
/* Allocation dst_s de 20 (chaine de 19 car. max) */
dst_s = calloc(20, sizeof*dst_s);
if (dst_s)
{
/* On popule une premiere fois dst_s*/
strncat(dst_s, part1_s, 19);
/* On affiche */
puts("CHAINE ORIGINALE");
puts(dst_s);
/* On souhaite un peu de place en plus */
/* On passe a une taille de 50, soit 49 car. max */
/* On utilise pour cela une variable pointeur temporaire*/
dst_s_sav = realloc(dst_s, 50);
if (dst_s_sav)
{
size_t lng;
/* Reallocation reussie, on recupere le nouveau bloc */
dst_s = dst_s_sav;
/* ATTENTION, ne pas oublier de retrancher le nombre de
caractères effectivement ecrits dans le buffer original */
lng = (strlen(part1_s)<19) ? strlen(part1_s) : 19;
strncat(dst_s, part2_s, 50-lng);
puts("CHAINE AGRANDIE");
puts(dst_s);
}
else
{
puts("Pas pu agrandir dst_s...");
}
free(dst_s);
}
else
{
perror("Allocation de dst_s non reussie");
}
return 0;
}Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Bah, j'en reviens à la première question, quid du nombre max de
caractères correspondant au critère dans la chaine parsée ?
Utiliser realloc() est deja bien plus souple que de faire un malloc() du
nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment
viable dans ton contexte, sachant que realloc demande deja quelques
precautions.
Exple (append a faire en fonction du parsing):
#include <stdio.h>
char * appendChar(char * s, size_t lng, char c)
{
if (s != NULL)
{
size_t pos = strlen(s);
if (pos < lng-1)
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
int main(void)
{
/* Chaine destination a bien dimensionner, 100 ici (99 car. max) */
char dst_arr[100];
dst_arr[0] = ' ';
/* Les append a faire en fonction du parsing */
/* Traitement a mettre dans une fonction par exemple */
appendChar(dst_arr,100,'a');
appendChar(dst_arr,100,'b');
appendChar(dst_arr,100,'c');
/* etc ...*/
puts(dst_arr);
return 0;
}
La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Voir realloc().
C'est une solution, mais que je préfère réallouer des blocs conséquents,
je ne m'amuserais pas a utiliser une telle solution pour rajouter un
caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change
pas (peut etre tronque si taille demandée plus petite)), tu gardes le
bloc précédemment alloué, soit l'agrandissement marche, soit il ne
marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Exple :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char * dst_s, * dst_s_sav;
char * part1_s = "Il y a une ";
char * part2_s = "greve a l'aeroport de Brest et ca m'emmerde beaucoup";
/* Allocation dst_s de 20 (chaine de 19 car. max) */
dst_s = calloc(20, sizeof*dst_s);
if (dst_s)
{
/* On popule une premiere fois dst_s*/
strncat(dst_s, part1_s, 19);
/* On affiche */
puts("CHAINE ORIGINALE");
puts(dst_s);
/* On souhaite un peu de place en plus */
/* On passe a une taille de 50, soit 49 car. max */
/* On utilise pour cela une variable pointeur temporaire*/
dst_s_sav = realloc(dst_s, 50);
if (dst_s_sav)
{
size_t lng;
/* Reallocation reussie, on recupere le nouveau bloc */
dst_s = dst_s_sav;
/* ATTENTION, ne pas oublier de retrancher le nombre de
caractères effectivement ecrits dans le buffer original */
lng = (strlen(part1_s)<19) ? strlen(part1_s) : 19;
strncat(dst_s, part2_s, 50-lng);
puts("CHAINE AGRANDIE");
puts(dst_s);
}
else
{
puts("Pas pu agrandir dst_s...");
}
free(dst_s);
}
else
{
perror("Allocation de dst_s non reussie");
}
return 0;
}
Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Bah, j'en reviens à la première question, quid du nombre max de
caractères correspondant au critère dans la chaine parsée ?
Utiliser realloc() est deja bien plus souple que de faire un malloc() du
nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment
viable dans ton contexte, sachant que realloc demande deja quelques
precautions.
Exple (append a faire en fonction du parsing):
#include <stdio.h>
char * appendChar(char * s, size_t lng, char c)
{
if (s != NULL)
{
size_t pos = strlen(s);
if (pos < lng-1)
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
int main(void)
{
/* Chaine destination a bien dimensionner, 100 ici (99 car. max) */
char dst_arr[100];
dst_arr[0] = ' ';
/* Les append a faire en fonction du parsing */
/* Traitement a mettre dans une fonction par exemple */
appendChar(dst_arr,100,'a');
appendChar(dst_arr,100,'b');
appendChar(dst_arr,100,'c');
/* etc ...*/
puts(dst_arr);
return 0;
}La solution que j'aurais tendance à utiliser est que quand je vois que
la taille devient trop courte, je sauvegarde ma chaine de caractere
(avec strcpy) chaineDest, je lui realloue la taille qu'il faut avec un
malloc, et je recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille plus grande.
Voir realloc().
C'est une solution, mais que je préfère réallouer des blocs conséquents,
je ne m'amuserais pas a utiliser une telle solution pour rajouter un
caractère. Avec realloc(), pas de strcpy a faire (le contenu ne change
pas (peut etre tronque si taille demandée plus petite)), tu gardes le
bloc précédemment alloué, soit l'agrandissement marche, soit il ne
marche pas auqel cas tu gardes le pointeur sur le bloc précédemment alloué.
Exple :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char * dst_s, * dst_s_sav;
char * part1_s = "Il y a une ";
char * part2_s = "greve a l'aeroport de Brest et ca m'emmerde beaucoup";
/* Allocation dst_s de 20 (chaine de 19 car. max) */
dst_s = calloc(20, sizeof*dst_s);
if (dst_s)
{
/* On popule une premiere fois dst_s*/
strncat(dst_s, part1_s, 19);
/* On affiche */
puts("CHAINE ORIGINALE");
puts(dst_s);
/* On souhaite un peu de place en plus */
/* On passe a une taille de 50, soit 49 car. max */
/* On utilise pour cela une variable pointeur temporaire*/
dst_s_sav = realloc(dst_s, 50);
if (dst_s_sav)
{
size_t lng;
/* Reallocation reussie, on recupere le nouveau bloc */
dst_s = dst_s_sav;
/* ATTENTION, ne pas oublier de retrancher le nombre de
caractères effectivement ecrits dans le buffer original */
lng = (strlen(part1_s)<19) ? strlen(part1_s) : 19;
strncat(dst_s, part2_s, 50-lng);
puts("CHAINE AGRANDIE");
puts(dst_s);
}
else
{
puts("Pas pu agrandir dst_s...");
}
free(dst_s);
}
else
{
perror("Allocation de dst_s non reussie");
}
return 0;
}Mais ca me parait abérant de faire ça pour toute concaténation en C ...
J'aime croire que le C n'est pas si barbare qu'on le dit, mais que c'est
plutot parce que je suis plus que juste en C ...
Bah, j'en reviens à la première question, quid du nombre max de
caractères correspondant au critère dans la chaine parsée ?
Utiliser realloc() est deja bien plus souple que de faire un malloc() du
nouveau, un strcpy() puis un free() du precedent mais est-ce vraiment
viable dans ton contexte, sachant que realloc demande deja quelques
precautions.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
qu'utilises-tu quoi à la place de strncpy(), strncat() ?
du snprintf() ?
strncat(), je ne lui vois vraiment aucun remplaçant valable.
en quoi se trompe-t-on dans les tailles pour strncpy() si on utilise :
{
char * source;
char dest[XXX];
/* ... */
strncpy(dest, source, sizeof(dest));
dest[sizeof(dest) - 1] = ' ';
}
strtok() et gets(), il y a bien strtok_r() et fgets(),
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
qu'utilises-tu quoi à la place de strncpy(), strncat() ?
du snprintf() ?
strncat(), je ne lui vois vraiment aucun remplaçant valable.
en quoi se trompe-t-on dans les tailles pour strncpy() si on utilise :
{
char * source;
char dest[XXX];
/* ... */
strncpy(dest, source, sizeof(dest));
dest[sizeof(dest) - 1] = ' ';
}
strtok() et gets(), il y a bien strtok_r() et fgets(),
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
PS: strncpy(), strncat(), strtok(), gets()... just say no.
qu'utilises-tu quoi à la place de strncpy(), strncat() ?
du snprintf() ?
strncat(), je ne lui vois vraiment aucun remplaçant valable.
en quoi se trompe-t-on dans les tailles pour strncpy() si on utilise :
{
char * source;
char dest[XXX];
/* ... */
strncpy(dest, source, sizeof(dest));
dest[sizeof(dest) - 1] = ' ';
}
strtok() et gets(), il y a bien strtok_r() et fgets(),
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
quoique strtok_r() n'est pas forcément C99, voire pas du tout.
En fait je "parse" un char* caractere par caractere, et je
concatene ces caracteres dans une autre chaine
(chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je
lui mets une taille de 20, et que j'ai besoin ensuite de
lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand
je vois que la taille devient trop courte, je sauvegarde
ma chaine de caractere (avec strcpy) chaineDest, je lui
realloue la taille qu'il faut avec un malloc, et je
recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille
plus grande.
En fait je "parse" un char* caractere par caractere, et je
concatene ces caracteres dans une autre chaine
(chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je
lui mets une taille de 20, et que j'ai besoin ensuite de
lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand
je vois que la taille devient trop courte, je sauvegarde
ma chaine de caractere (avec strcpy) chaineDest, je lui
realloue la taille qu'il faut avec un malloc, et je
recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille
plus grande.
En fait je "parse" un char* caractere par caractere, et je
concatene ces caracteres dans une autre chaine
(chaineDest) de caractere char*.
Le probleme est que ma chaine chaineDest, si au depart je
lui mets une taille de 20, et que j'ai besoin ensuite de
lui concatener plus de 20 caracteres, comment je fais ?
La solution que j'aurais tendance à utiliser est que quand
je vois que la taille devient trop courte, je sauvegarde
ma chaine de caractere (avec strcpy) chaineDest, je lui
realloue la taille qu'il faut avec un malloc, et je
recopie ensuite dans l'autre sens pour remettre le contenu
de ma chaine sauvegardé dans la nouvelle chaine de taille
plus grande.
"gadget" wrote in message
news:Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Mauvais conseil.
L'OP est visiblement un débutant en C, realloc() est bien top piégeuse pour être
une solution adéquate à son problème.
Je n'ai pas compris pourquoi on doit "sauvegarder" chaineDest avant de "lui"
reallouer la taille supplémentaire. Poster le code nous permettrait une analyse
en ligne et serait riche d'enseignements pour l'OP. Ce sujet est d'ailleurs
récurrent sur ce forum.
J'ajouterais un élément de réponse : la plupart des concaténations qui semblent
efficaces dans d'autres langages (Basic, C++, PHP, Perl...) déclenchent en fait
quasi systématiquement une allocation mémoire pour chaque opération
intermédiaire. En C, c'est le programmeur qui est en charge. Dans un programme
qui fait des concatenations nombreuses et consécutives sur la meme destination,
on peut choisir de réallouer le buffer destination d'une taille plus grande
quand c'est nécessaire, pour éviter d'avoir à le faire pour chaque opération,
quitte à réduire la taille finale au besoin par une opération adéquate. On peut
en particulier avoir recours à des heuristiques sophistiquées pour déterminer de
combien surallouer au fur et à mesure des besoins : progression géométrique,
fibonacci, exponentielle...
Programmer ce genre de choses en C est donc beaucoup plus laborieux, et peut
donc conduire à une grande variété d'implémentations, certaines lentes, d'autres
rapides mais dispendieuses, et de nombreuses avec des erreurs plus ou moins
graves.
Chqrlie.
"gadget" <anti@spam.org> wrote in message
news:pan.2004.11.13.23.23.47.442956@spam.org...
Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Mauvais conseil.
L'OP est visiblement un débutant en C, realloc() est bien top piégeuse pour être
une solution adéquate à son problème.
Je n'ai pas compris pourquoi on doit "sauvegarder" chaineDest avant de "lui"
reallouer la taille supplémentaire. Poster le code nous permettrait une analyse
en ligne et serait riche d'enseignements pour l'OP. Ce sujet est d'ailleurs
récurrent sur ce forum.
J'ajouterais un élément de réponse : la plupart des concaténations qui semblent
efficaces dans d'autres langages (Basic, C++, PHP, Perl...) déclenchent en fait
quasi systématiquement une allocation mémoire pour chaque opération
intermédiaire. En C, c'est le programmeur qui est en charge. Dans un programme
qui fait des concatenations nombreuses et consécutives sur la meme destination,
on peut choisir de réallouer le buffer destination d'une taille plus grande
quand c'est nécessaire, pour éviter d'avoir à le faire pour chaque opération,
quitte à réduire la taille finale au besoin par une opération adéquate. On peut
en particulier avoir recours à des heuristiques sophistiquées pour déterminer de
combien surallouer au fur et à mesure des besoins : progression géométrique,
fibonacci, exponentielle...
Programmer ce genre de choses en C est donc beaucoup plus laborieux, et peut
donc conduire à une grande variété d'implémentations, certaines lentes, d'autres
rapides mais dispendieuses, et de nombreuses avec des erreurs plus ou moins
graves.
Chqrlie.
"gadget" wrote in message
news:Regarde du coté de la fonction realloc. C'est typiquement sont type
d'utilisation.
Mauvais conseil.
L'OP est visiblement un débutant en C, realloc() est bien top piégeuse pour être
une solution adéquate à son problème.
Je n'ai pas compris pourquoi on doit "sauvegarder" chaineDest avant de "lui"
reallouer la taille supplémentaire. Poster le code nous permettrait une analyse
en ligne et serait riche d'enseignements pour l'OP. Ce sujet est d'ailleurs
récurrent sur ce forum.
J'ajouterais un élément de réponse : la plupart des concaténations qui semblent
efficaces dans d'autres langages (Basic, C++, PHP, Perl...) déclenchent en fait
quasi systématiquement une allocation mémoire pour chaque opération
intermédiaire. En C, c'est le programmeur qui est en charge. Dans un programme
qui fait des concatenations nombreuses et consécutives sur la meme destination,
on peut choisir de réallouer le buffer destination d'une taille plus grande
quand c'est nécessaire, pour éviter d'avoir à le faire pour chaque opération,
quitte à réduire la taille finale au besoin par une opération adéquate. On peut
en particulier avoir recours à des heuristiques sophistiquées pour déterminer de
combien surallouer au fur et à mesure des besoins : progression géométrique,
fibonacci, exponentielle...
Programmer ce genre de choses en C est donc beaucoup plus laborieux, et peut
donc conduire à une grande variété d'implémentations, certaines lentes, d'autres
rapides mais dispendieuses, et de nombreuses avec des erreurs plus ou moins
graves.
Chqrlie.