Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être
initialisée.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais
l'apprentissage de ces langages, pas l'ordre historique de leur conception. C
est antérieur à PHP, Perl, C++, java... Seules des versions primitives et
obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore
relativement vert, et dont on respecte avec humilité les limitations.
Chqrlie.
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être
initialisée.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais
l'apprentissage de ces langages, pas l'ordre historique de leur conception. C
est antérieur à PHP, Perl, C++, java... Seules des versions primitives et
obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore
relativement vert, et dont on respecte avec humilité les limitations.
Chqrlie.
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
tempLine[0]=' ';
Cette ligne est inutile, la destination de strcpy() n'a pas besoin d'être
initialisée.
Oui. Mais l'emploi du passé correspond uniquement à l'ordre dans lequel tu fais
l'apprentissage de ces langages, pas l'ordre historique de leur conception. C
est antérieur à PHP, Perl, C++, java... Seules des versions primitives et
obsolètes de Basic le précèdent. Donc c'est plutot un ancêtre encore
relativement vert, et dont on respecte avec humilité les limitations.
Chqrlie.
Charlie Gordon wrote:
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
Ces lignes sont en fait dans un while sur un fgets
while(fgets(buffer,sizeof(buffer),fp)) {
BUFFER_SIZE etant donc la taille du buffer utilisé. nbBuffer étant le
numero du buffer actuellement traité (pour savoir si on a du de nouveau
faire un malloc car la taille etait trop petite).
Charlie Gordon wrote:
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
Ces lignes sont en fait dans un while sur un fgets
while(fgets(buffer,sizeof(buffer),fp)) {
BUFFER_SIZE etant donc la taille du buffer utilisé. nbBuffer étant le
numero du buffer actuellement traité (pour savoir si on a du de nouveau
faire un malloc car la taille etait trop petite).
Charlie Gordon wrote:
Je ne comprends pas la logique des BUFFER_SIZE ici.
Ni la soustraction nbBuffer-1
Et il manque au moins un char pour le ' ' final : il faut len+1.
Enfin en C sizeof(char) vaut 1 par definition.
Ces lignes sont en fait dans un while sur un fgets
while(fgets(buffer,sizeof(buffer),fp)) {
BUFFER_SIZE etant donc la taille du buffer utilisé. nbBuffer étant le
numero du buffer actuellement traité (pour savoir si on a du de nouveau
faire un malloc car la taille etait trop petite).
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)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
#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);
quel drole de nom pour cette variable temporaire : dst_s_sav.
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;
En fait c'est tout simplement : lng = strlen(dst_s);
strncat(dst_s, part2_s, 50-lng);
pas de bol, c'est 49-lng. Et encore on suppose que lng < 49, sinon ca fera un
debordement de tableau.
strncat() est un faux ami.
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)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
#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);
quel drole de nom pour cette variable temporaire : dst_s_sav.
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;
En fait c'est tout simplement : lng = strlen(dst_s);
strncat(dst_s, part2_s, 50-lng);
pas de bol, c'est 49-lng. Et encore on suppose que lng < 49, sinon ca fera un
debordement de tableau.
strncat() est un faux ami.
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)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
{
s[pos++] = c;
s[pos] = ' ';
}
}
return s;
}
#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);
quel drole de nom pour cette variable temporaire : dst_s_sav.
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;
En fait c'est tout simplement : lng = strlen(dst_s);
strncat(dst_s, part2_s, 50-lng);
pas de bol, c'est 49-lng. Et encore on suppose que lng < 49, sinon ca fera un
debordement de tableau.
strncat() est un faux ami.
"Kinou" wrote in message
news:4197b268$0$2411$
Ah, je viens de comprendre.
C'est la suite de ta file "Travailler sur de gros fichiers".
J'ai relu ton code de readByLine().
Cette fonction lit une ligne complete, éventuellement très longue, et en renvoie
une copie allouée par malloc().
Il y avait dans ton code plusieurs problemes :
- tu testes buffer[len-1] sans vérifier que len est > 0.
on peut supposer que len n'est jamais nul, mais ce n'est pas prudent.
- tu ne testes pas le résultat de l'allocation mémoire.
- la gestion de la taille déjà lue est trop lourde parce que tu utilises un
compte de buffers plutot qu'un compte de caractères.
- tu mélanges l'anglais et le francais dans les noms de variables, c'est confus.
Voici une version simplifiee :
/* Cette fonction lit une ligne complete et retourne
* une copie allouée par malloc()
*/
char *readOneLine(FILE *fp)
{
char buffer[BUFFER_SIZE];
char *line, *newLine;
int len, done, lineLength;
line = NULL;
lineLength = 0;
done = 0;
while (!done && fgets(buffer, sizeof(buffer), fp)) {
len = strlen(buffer);
// Nous sommes a la fin de la line
if (len > 0 && buffer[len - 1] == 'n') {
buffer[len - 1] = ' ';
len--;
done = 1;
}
newLine = (char *)malloc(lineLength + len + 1);
if (!newLine) {
// Allocation memoire impossible, il faudrait sans
// doute signaler ce probleme.
free(line);
return NULL;
}
if (line) {
// recopie de la partie déjà lue, sauf la premiere fois
// en fait ce test est inutile, mais il rend le code
// plus comprehensible.
memcpy(newLine, line, lineLength);
free(line);
line = NULL;
}
// recopie du dernier buffer lu en fin de bloc
// on pourrait faire un peu plus rapide avec memcpy
strcpy(newLine + lineLength, buffer);
lineLength += len;
line = newLine;
newLine = NULL;
}
// En fin de fichier ou en fin de line, on renvoie la partie
// deja lue. s'il n'y avait plus rien à lire, line==NULL
return line;
}
On pourrait faire un peu plus simple et plus efficace avec realloc(), mais le
mecanisme est
plus clair en faisant l'allocation a la main, et realloc() est un peu trop
piegeuse pour un débutant ;-)
Yep si il y a quelquechose que j'ai compris, c'est ca ;-)
--
Chqrlie.
"Kinou" <kinou@animezvous.com> wrote in message
news:4197b268$0$2411$626a14ce@news.free.fr...
Ah, je viens de comprendre.
C'est la suite de ta file "Travailler sur de gros fichiers".
J'ai relu ton code de readByLine().
Cette fonction lit une ligne complete, éventuellement très longue, et en renvoie
une copie allouée par malloc().
Il y avait dans ton code plusieurs problemes :
- tu testes buffer[len-1] sans vérifier que len est > 0.
on peut supposer que len n'est jamais nul, mais ce n'est pas prudent.
- tu ne testes pas le résultat de l'allocation mémoire.
- la gestion de la taille déjà lue est trop lourde parce que tu utilises un
compte de buffers plutot qu'un compte de caractères.
- tu mélanges l'anglais et le francais dans les noms de variables, c'est confus.
Voici une version simplifiee :
/* Cette fonction lit une ligne complete et retourne
* une copie allouée par malloc()
*/
char *readOneLine(FILE *fp)
{
char buffer[BUFFER_SIZE];
char *line, *newLine;
int len, done, lineLength;
line = NULL;
lineLength = 0;
done = 0;
while (!done && fgets(buffer, sizeof(buffer), fp)) {
len = strlen(buffer);
// Nous sommes a la fin de la line
if (len > 0 && buffer[len - 1] == 'n') {
buffer[len - 1] = ' ';
len--;
done = 1;
}
newLine = (char *)malloc(lineLength + len + 1);
if (!newLine) {
// Allocation memoire impossible, il faudrait sans
// doute signaler ce probleme.
free(line);
return NULL;
}
if (line) {
// recopie de la partie déjà lue, sauf la premiere fois
// en fait ce test est inutile, mais il rend le code
// plus comprehensible.
memcpy(newLine, line, lineLength);
free(line);
line = NULL;
}
// recopie du dernier buffer lu en fin de bloc
// on pourrait faire un peu plus rapide avec memcpy
strcpy(newLine + lineLength, buffer);
lineLength += len;
line = newLine;
newLine = NULL;
}
// En fin de fichier ou en fin de line, on renvoie la partie
// deja lue. s'il n'y avait plus rien à lire, line==NULL
return line;
}
On pourrait faire un peu plus simple et plus efficace avec realloc(), mais le
mecanisme est
plus clair en faisant l'allocation a la main, et realloc() est un peu trop
piegeuse pour un débutant ;-)
Yep si il y a quelquechose que j'ai compris, c'est ca ;-)
--
Chqrlie.
"Kinou" wrote in message
news:4197b268$0$2411$
Ah, je viens de comprendre.
C'est la suite de ta file "Travailler sur de gros fichiers".
J'ai relu ton code de readByLine().
Cette fonction lit une ligne complete, éventuellement très longue, et en renvoie
une copie allouée par malloc().
Il y avait dans ton code plusieurs problemes :
- tu testes buffer[len-1] sans vérifier que len est > 0.
on peut supposer que len n'est jamais nul, mais ce n'est pas prudent.
- tu ne testes pas le résultat de l'allocation mémoire.
- la gestion de la taille déjà lue est trop lourde parce que tu utilises un
compte de buffers plutot qu'un compte de caractères.
- tu mélanges l'anglais et le francais dans les noms de variables, c'est confus.
Voici une version simplifiee :
/* Cette fonction lit une ligne complete et retourne
* une copie allouée par malloc()
*/
char *readOneLine(FILE *fp)
{
char buffer[BUFFER_SIZE];
char *line, *newLine;
int len, done, lineLength;
line = NULL;
lineLength = 0;
done = 0;
while (!done && fgets(buffer, sizeof(buffer), fp)) {
len = strlen(buffer);
// Nous sommes a la fin de la line
if (len > 0 && buffer[len - 1] == 'n') {
buffer[len - 1] = ' ';
len--;
done = 1;
}
newLine = (char *)malloc(lineLength + len + 1);
if (!newLine) {
// Allocation memoire impossible, il faudrait sans
// doute signaler ce probleme.
free(line);
return NULL;
}
if (line) {
// recopie de la partie déjà lue, sauf la premiere fois
// en fait ce test est inutile, mais il rend le code
// plus comprehensible.
memcpy(newLine, line, lineLength);
free(line);
line = NULL;
}
// recopie du dernier buffer lu en fin de bloc
// on pourrait faire un peu plus rapide avec memcpy
strcpy(newLine + lineLength, buffer);
lineLength += len;
line = newLine;
newLine = NULL;
}
// En fin de fichier ou en fin de line, on renvoie la partie
// deja lue. s'il n'y avait plus rien à lire, line==NULL
return line;
}
On pourrait faire un peu plus simple et plus efficace avec realloc(), mais le
mecanisme est
plus clair en faisant l'allocation a la main, et realloc() est un peu trop
piegeuse pour un débutant ;-)
Yep si il y a quelquechose que j'ai compris, c'est ca ;-)
--
Chqrlie.
Merci ! memcpy est plus efficace que strcpy ?
Merci ! memcpy est plus efficace que strcpy ?
Merci ! memcpy est plus efficace que strcpy ?
"Charlie Gordon" wrote in message
news:<cn6ho9$5m$...
char * appendChar(char * s, size_t lng, char c) {
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct
avec toutefois un avertissement sur la comparaison signé/non signé.
"Charlie Gordon" wrote in message
news:<cn6ho9$5m$1@reader1.imaginet.fr>...
char * appendChar(char * s, size_t lng, char c) {
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct
avec toutefois un avertissement sur la comparaison signé/non signé.
"Charlie Gordon" wrote in message
news:<cn6ho9$5m$...
char * appendChar(char * s, size_t lng, char c) {
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct
avec toutefois un avertissement sur la comparaison signé/non signé.
Merci ! memcpy est plus efficace que strcpy ?
Merci ! memcpy est plus efficace que strcpy ?
Merci ! memcpy est plus efficace que strcpy ?
"Charlie Gordon" wrote in message
news:<cn6ho9$5m$...
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est
trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct avec toutefois un avertissement
sur la comparaison signé/non signé.
strncat() est un faux ami.
Aïe, mea culpa, surtout après le gros thread des jours derniers sur
strncpy/strncat et les nombreuse propositions. Mais je reste sur mon
opinion concernant strncat, le fait est simplement que je ne le
maitrîse pas encore. Pour lng < 49, pas de pb, ici j'avais mis part1_s
en dur mais je fais plus de contrôles dans la vraie vie ;) quand je
code.
"Charlie Gordon" <news@chqrlie.org> wrote in message
news:<cn6ho9$5m$1@reader1.imaginet.fr>...
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est
trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct avec toutefois un avertissement
sur la comparaison signé/non signé.
strncat() est un faux ami.
Aïe, mea culpa, surtout après le gros thread des jours derniers sur
strncpy/strncat et les nombreuse propositions. Mais je reste sur mon
opinion concernant strncat, le fait est simplement que je ne le
maitrîse pas encore. Pour lng < 49, pas de pb, ici j'avais mis part1_s
en dur mais je fais plus de contrôles dans la vraie vie ;) quand je
code.
"Charlie Gordon" wrote in message
news:<cn6ho9$5m$...
size_t pos = strlen(s);
if (pos < lng-1)
les unsigned ont encore frappé !
ce test se vautre si lng vaut 0
il faut mieux écrire pos + 1 < lng
ou utiliser des ssize_t ou des int pour les tailles de tableau.
qui plus est lng est mal choisi comme nom pour la taille du tableau, c'est
trop
ambigu, on pourrait confondre avec la longueur de la chaine qui s'y trouve.
Aïe, bien vu, je me suis dit aujourd'hui "Tiens, je pourrais corriger
par if (pos < (int)(lng-1))", et là, erreur fatale (cause priorité
opérateurs), ça revient au même et c'est pire, ca obfusque davantage.
if (pos < (int)lng-1) serait correct avec toutefois un avertissement
sur la comparaison signé/non signé.
strncat() est un faux ami.
Aïe, mea culpa, surtout après le gros thread des jours derniers sur
strncpy/strncat et les nombreuse propositions. Mais je reste sur mon
opinion concernant strncat, le fait est simplement que je ne le
maitrîse pas encore. Pour lng < 49, pas de pb, ici j'avais mis part1_s
en dur mais je fais plus de contrôles dans la vraie vie ;) quand je
code.
Kinou wrote on 15/11/04 :Merci ! memcpy est plus efficace que strcpy ?
Oui, si on connait la longueur à copier. Sinon, on doit utiliser
strlen(), et on tombe dans le même travers que strcpy() (temps qui
s'allonge avec la taille de la chaine).
Kinou wrote on 15/11/04 :
Merci ! memcpy est plus efficace que strcpy ?
Oui, si on connait la longueur à copier. Sinon, on doit utiliser
strlen(), et on tombe dans le même travers que strcpy() (temps qui
s'allonge avec la taille de la chaine).
Kinou wrote on 15/11/04 :Merci ! memcpy est plus efficace que strcpy ?
Oui, si on connait la longueur à copier. Sinon, on doit utiliser
strlen(), et on tombe dans le même travers que strcpy() (temps qui
s'allonge avec la taille de la chaine).
Tu peux tenter d'analyser le contenu du header string.h de la lib C. C'est
particulièrement instructif.
Tu peux tenter d'analyser le contenu du header string.h de la lib C. C'est
particulièrement instructif.
Tu peux tenter d'analyser le contenu du header string.h de la lib C. C'est
particulièrement instructif.