Comment lire un fichier csv avec séparateur ; pour structure
Rhamm94
Messages postés
13
Statut
Membre
-
Rhamm94 Messages postés 13 Statut Membre -
Rhamm94 Messages postés 13 Statut Membre -
Bonjour,
Je souhaiterais savoir comment lire un fichier csv avec séparateur ";".
Car je voudrais renseigné une structure avec les informations lus dans un fichier.
ex :
nom;prenom;date_de_naissance;lieu_de_naissance;
Mais aussi prendre en compte les champs vide afin de ne pas perturber ma structure
ex :
nom;prenom;;lieu_de_naissance;
Mais aussi comment récupérer ces infos et renvoyer ces valeurs dans m structure ?
Merci pour votre aide.
Je souhaiterais savoir comment lire un fichier csv avec séparateur ";".
Car je voudrais renseigné une structure avec les informations lus dans un fichier.
ex :
nom;prenom;date_de_naissance;lieu_de_naissance;
Mais aussi prendre en compte les champs vide afin de ne pas perturber ma structure
ex :
nom;prenom;;lieu_de_naissance;
Mais aussi comment récupérer ces infos et renvoyer ces valeurs dans m structure ?
Merci pour votre aide.
A voir également:
- Nombre de colonnes invalides dans les données csv à la ligne 1.
- Partage de photos en ligne - Guide
- Comment faire deux colonnes indépendantes dans word - Guide
- Aller à la ligne excel - Guide
- Supprimer les données de navigation - Guide
- Classer par ordre alphabétique excel plusieurs colonnes - Guide
4 réponses
Ci dessous l'ébauche du code. (je ne voudrais pas qu'on pense que j'attend que quelqu'un fasse mon travail.)
Par contre j'ai vraiment besoin d'un coup de main.
Merci d'avance.
Par contre j'ai vraiment besoin d'un coup de main.
Merci d'avance.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
struct Adresse
{
char Societe[40];
int ClientSite;
int ClientCompta;
char Groupe[50];
char Fjuri[54];
char Nom[45];
char Enseigne[45];
char Adresse1[45];
char Adresse2[45];
int Cpost;
char Ville[45];
int Tel;
int Fax;
char Email[40];
int Siret;
};
int nbLignesAdresseClients(void);
char *dest;
char *fichier;
struct Adresse client[nbLignesAdresseClients] ;
Int nbClient ;
Char *membresAdresse[14] ;
char *fichierAdresseClient="Adresse clients.csv"; // NOUVEAU
char *copieFichierAdresseClient="Donnees/Adresse Clients.txt"; // ANCIEN
int main()
{
lireFichierAdresse;
montrer();
ecrireFichierAdresse;
return(0);
}
int compte(FILE *fichierLignes) /* compteur de lignes */
{
int c;
int nLignes = 0;
int c2 = '\0';
while((c=fgetc(fichierLignes)) != EOF)
{
if(c=='\n')
nLignes++;
c2 = c;
}
/* Ici, c2 est égal au caractère juste avant le EOF. */
if(c2 != '\n')nLignes++; /* Dernière ligne non finie */
return nLignes;
}
int nbLignesAdresseClients(void) /*Compteur lignes fichier Adresse Clients */
{
FILE *fichierLignes = fopen(fichierAdresseClient, "r");
if(fichierAdresse != NULL)
{
int nLignes = compte(fichierLignes);
printf("Nombre de lignes : %d\n", nLignes);
fclose(fichierLignes);
}
else
puts("Erreur en ouverture du fichier : Adresses Clients.");
return 0;
}
void lireFichierAdresse(void)
{
FILE *f;
struct Adresse charge;
f = fopen(fichierAdresseClients, "r");
if(!f) /* Fichier introuvable !*/
return;
/* Lecture totale */
while(fread(&client, sizeof(client), 1, f))
{
void lectureChampsAdresse (f);
/* Lecture des valeurs du fichier, */
client.Societe=charge.Societe;
client.ClientSite=charge.ClientSite;
client.ClientCompta=charge.ClientCompta;
client.Groupe=charge.Groupe;
client.Fjuri=charge.Fjuri;
client.Nom=charge.Nom;
client.Enseigne=charge.Enseigne;
client.Adresse1=charge.Adresse1;
client.Adresse2=charge.Adresse2;
client.Cpost=charge.Cpost;
client.Ville=charge.Ville;
client.Tel=charge.Tel;
client.Fax=charge.Fax;
client.Email=charge.Email;
client.Siret=charge.Siret;
/* pas des pointeurs ! */
}
fclose(f);
}
void ecrireFichierAdresse(void)
{
FILE *f;
if(client == NULL) /* Liste vide */
{
puts("Rien a sauvegarder !");
return;
}
f = fopen(copieFichierAdresseClient, "w");
if(!f)
{
puts("Erreur en ouverture de fichier");
exit(1);
}
while(client) /* Dernier enreg == NULL */
{
fwrite(&client, sizeof(client), 1, f);
}
fclose(f);
} ;
/* Affiche tous les enregistrements de la liste */
void montrer(void)
{
if(client == NULL) /* Liste vide */
{
puts("Rien a afficher");
return;
}
puts("Affichage complet :");
while(client) /* Dernier == NULL */
{
printf("%s\n",client.Societe);
printf("%d\n",client.ClientSite);
printf("%d\n",client.ClientCompta);
printf("%s\n",client.Groupe);
printf("%s\n",client.Fjuri);
printf("%s\n",client.Nom);
printf("%s\n",client.Enseigne);
printf("%s\n",client.Adresse1);
printf("%s\n",client.Adresse2);
printf("%s\n",client.Cpost);
printf("%s\n",client.Ville);
printf("%d\n",client.Tel);
printf("%d\n",client.Fax);
printf("%s\n",client.Email);
printf("%d\n",client.Siret);
}
} ;
void lectureChampsAdresse (char* dest, File* fichierLu) //lecture d'un champ
{
int i=0
int a=0
Adresse charge;
Char site [20] = {0};
Char comptable [20] = {0};
Char cp [5] = {0};
while (a < 14)
{
c=fgetc(fichierLu) ; // on lit le caractere
if (c !=EOF && c!= `;')dest[i]=c; //si le caractere est valide
i++; // on passe au caractere suivant
membresAdresse[a] = dest //on enregistre la valeur dans un tableau de char
a++ ;
}
Site = membresAdresse[1] ;
Comptable = membresAdresse[2];
Cp = membresAdresse[9];
if (site, 20)
{
// Si lecture du texte ok, convertir le nombre en long et
le retourner
return strtol(site, NULL, 10);
}
else
{
// Si problème de lecture, renvoyer 0
return 0;
}
membresAdresse[1] = site ;
if (comptable, 20)
{
// Si lecture du texte ok, convertir le nombre en long et
le retourner
return strtol(comptable, NULL, 10);
}
else
{
// Si problème de lecture, renvoyer 0
return 0;
}
membresAdresse[2] = comptable ;
if (cp, 20)
{
// Si lecture du texte ok, convertir le nombre en long et
le retourner
return strtol(cp, NULL, 10);
}
else
{
// Si problème de lecture, renvoyer 0
return 0;
}
membresAdresse[9] = cp ;
charge.Societe = membresAdresse[0];
charge.ClientSite = membresAdresse[1];
charge.ClientCompta = membresAdresse[2];
charge.Groupe = membresAdresse[3];
charge.Fjuri = membresAdresse[4];
charge.Nom = membresAdresse[5];
charge.Enseigne = membresAdresse[6];
charge.Adresse1 = membresAdresse[7];
charge.Adresse2 = membresAdresse[8];
charge.Cpost = membresAdresse[9];
charge.Ville = membresAdresse[10];
charge.Tel = membresAdresse[11];
charge.Fax = membresAdresse[12];
charge.Email = membresAdresse[13];
charge.Siret = membresAdresse[14];
While (c!=EOF && c != ` ;') ; //fin de lecture
Dest [i] = `\0'; //fin de chaine
}
Bonjour,
J'ai essayer de simplifier le programme, afin 'y aller étape par étape, mai s je ne comprends pas ou cela bogue.
Lorsque je le lance la consol s'ouvre et un message apparait me signalant que Windows n'a pas fonctionner.
J'ai essayer de simplifier le programme, afin 'y aller étape par étape, mai s je ne comprends pas ou cela bogue.
Lorsque je le lance la consol s'ouvre et un message apparait me signalant que Windows n'a pas fonctionner.
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // pour strchr()
#define TAILLE_MAX 1000
int recupererInfos(char *chaine, int longueur, FILE *fichier);
char *fgets( char *str, int num, FILE *stream );
char **str_split (char *s, const char *ct);
void ficlire(void);
int main(int argc, char *argv[])
{
lireFichier();
return 0;
}
int recupererInfos(char *chaine, int longueur, FILE *fichier)
{
char *positionEntree = NULL;
// On lit le texte du fichier
if (fgets(chaine, longueur, fichier) != NULL) // Pas d'erreur de saisie ?
{
positionEntree = strchr(chaine, '\n'); // On recherche l'"Entrée"
if (positionEntree != NULL) // Si on a trouvé le retour à la ligne
{
*positionEntree = '\0'; // On remplace ce caractère par \0
}
else
{
viderBuffer();
}
return 1; // On renvoie 1 si la fonction s'est déroulée sans erreur
}
else
{
viderBuffer();
return 0; // On renvoie 0 s'il y a eu une erreur
}
}
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
char **str_split (char *s, const char *ct)
{
char **tab = NULL;
if (s != NULL && ct != NULL)
{
int i;
char *cs = NULL;
size_t size = 1;
// Tant que strtok nous renvoi une adresse non nulle
for (i = 0; (cs = strtok (s, ct)); i++)
{
if (size <= i + 1)
{
void *tmp = NULL;
// on augmente la taille du tableau d'une case dans laquelle on stocke l'adresse retournée par (A)
size <<= 1;
tmp = realloc (tab, sizeof (*tab) * size);
if (tmp != NULL)
{
tab = tmp;
}
else
{
fprintf (stderr, "Memoire insuffisante\n");
free (tab);
tab = NULL;
exit (EXIT_FAILURE);
}
}
/* (A) */
tab[i] = cs;
s = NULL;
}
tab[i] = NULL;
}
return tab;
}
// lit un fichier ligne a ligne
void lireFichier(void)
{
static const char filename[] = "listebenevoles.csv";
FILE *f;
f = fopen(filename, "r");
if ( f != NULL )
{
while ( fgets ( ligne, sizeof ligne, f ) != NULL )
{
char *nom;
char *membres;
recupererInfos(nom, TAILLE_MAX, f);
membres = str_split (nom, ';');
printf(" %s",membres);
}
fclose ( f );
}
else
{
perror ( filename );
}
return (0);
}
Salut Rhamm94,
1.
En compilant ton programme, on a les warnings et erreurs suivants (avec gcc en compilant avec les warnings) :
Avec un compilateur normalement constitué (quel compilateur utilises-tu ?), ce programme ne compile pas, car "ligne" en ligne 105 de ton code n'est pas déclarée.
TAILLE_MAX, est-ce la taille maximale d'une ligne ?
Les warnings peuvent aussi cacher des problèmes et doivent être traités. Tu déclares une fonction ficlire() qui n'existe pas et tu ne déclares pas les fonctions qui existent (cf. warnings "implicit declaration of function"), les protypes de tes déclarations de fonctions doivent correspondre à leur implémentation (cf. warnings "conflicting types for"), si tes fonctions n'ont pas d'arguments, déclares les explicitement avec "void".
Dans un premier temps sert toi des messages du compilateur, en commençant par le premier warning ou erreur. Corrige le problème qui cause le warning ou l'erreur, et recompile. Passe ensuite au nouveau premier warning ou erreur signalé (qui peuvent être différents après la correction), etc... jusqu'à ce que tu arrives à faire fonctionner *une* fonctionnalité de ton programme (retire le code des fonctionnalités suivantes pour y voir clair). Ne passe pas à la fonctionnalité suivante, tant que tu n'as pas fait fonctionner la première fonctionnalité sans erreurs ni warnings à la compilation, et sans erreurs à l'exécution.
Lorsque ton compilateur ne se plaint plus de la forme de ton code, tu y vois plus clair pour t'interroger sur le fond et la logique de ton code.
2.
Quelques indications sur le fond.
Ta fonction recupererInfos() contient du code pour lire une ligne avec fgets (et tu n'as pas besoin de vider le buffer clavier, vu que ce n'est pas une saisie clavier qui est traitée, mais c'est une autre histoire). Alors, que dans ta fonction lireFichier(), qui appelle recupererInfos(), tu utilises déjà fgets pour lire une ligne (à condition que tu déclares ta variable, bien sur). Alors, il faut choisir où tu mets le code qui lit une ligne du fichier texte.
Là, ton code ne te permet pas de lire le fichier ligne par ligne. Essaye déjà de faire cela (sans *aucun* warning ni erreur) :
1- ouvrir le fichier
2- lire une ligne du fichier dans une chaîne de caractères C
3- afficher cette chaîne de caractères C
4- boucler sur 2 tant que le fichier contient des lignes
5- fermer le fichier
Poste ton code lorsque tu auras fait cela. Ensuite, tu pourras t'attaquer au traitement de chaque ligne.
3.
Enfin, dans ton énoncé de départ (c'est un devoir ?) tu indiquais que tu devais renseigner "une structure avec les informations". Là ta structure (
Si tu fais ce programme sans contraintes particulières, il est important de savoir quel est l'objectif et les fonctionnalités que tu attends de ton programme, et de décider en fonction de cela de la façon dont tu vas l'implémenter.
Par contre, si c'est un devoir et qu'on te demande d'utiliser des structures... ben... il faudra que tu les utilises.. non ?
Mais là on anticipe sur quelque chose qui dépasse la première étape, on verra cela quand tu auras produit un code correspondant à la fonctionnalité décrite en 2.
Dal
1.
En compilant ton programme, on a les warnings et erreurs suivants (avec gcc en compilant avec les warnings) :
$ gcc -Wall rhamm94_new.c
rhamm94_new.c: In function `main':
rhamm94_new.c:14:2: warning: implicit declaration of function `lireFichier' [-Wimplicit-function-declaration]
rhamm94_new.c: In function `recupererInfos':
rhamm94_new.c:35:4: warning: implicit declaration of function `viderBuffer' [-Wimplicit-function-declaration]
rhamm94_new.c: At top level:
rhamm94_new.c:46:6: warning: conflicting types for `viderBuffer' [enabled by default]
rhamm94_new.c:35:4: note: previous implicit declaration of `viderBuffer' was here
rhamm94_new.c:97:6: warning: conflicting types for `lireFichier' [enabled by default]
rhamm94_new.c:14:2: note: previous implicit declaration of `lireFichier' was here
rhamm94_new.c: In function `lireFichier':
rhamm94_new.c:105:19: error: `ligne' undeclared (first use in this function)
rhamm94_new.c:105:19: note: each undeclared identifier is reported only once for each function it appears in
rhamm94_new.c:113:4: warning: passing argument 2 of `str_split' makes pointer from integer without a cast [enabled by default]
rhamm94_new.c:55:8: note: expected `const char *' but argument is of type `int'
rhamm94_new.c:113:12: warning: assignment from incompatible pointer type [enabled by default]
rhamm94_new.c:125:2: warning: `return' with a value, in function returning void [enabled by default]
Avec un compilateur normalement constitué (quel compilateur utilises-tu ?), ce programme ne compile pas, car "ligne" en ligne 105 de ton code n'est pas déclarée.
TAILLE_MAX, est-ce la taille maximale d'une ligne ?
Les warnings peuvent aussi cacher des problèmes et doivent être traités. Tu déclares une fonction ficlire() qui n'existe pas et tu ne déclares pas les fonctions qui existent (cf. warnings "implicit declaration of function"), les protypes de tes déclarations de fonctions doivent correspondre à leur implémentation (cf. warnings "conflicting types for"), si tes fonctions n'ont pas d'arguments, déclares les explicitement avec "void".
Dans un premier temps sert toi des messages du compilateur, en commençant par le premier warning ou erreur. Corrige le problème qui cause le warning ou l'erreur, et recompile. Passe ensuite au nouveau premier warning ou erreur signalé (qui peuvent être différents après la correction), etc... jusqu'à ce que tu arrives à faire fonctionner *une* fonctionnalité de ton programme (retire le code des fonctionnalités suivantes pour y voir clair). Ne passe pas à la fonctionnalité suivante, tant que tu n'as pas fait fonctionner la première fonctionnalité sans erreurs ni warnings à la compilation, et sans erreurs à l'exécution.
Lorsque ton compilateur ne se plaint plus de la forme de ton code, tu y vois plus clair pour t'interroger sur le fond et la logique de ton code.
2.
Quelques indications sur le fond.
Ta fonction recupererInfos() contient du code pour lire une ligne avec fgets (et tu n'as pas besoin de vider le buffer clavier, vu que ce n'est pas une saisie clavier qui est traitée, mais c'est une autre histoire). Alors, que dans ta fonction lireFichier(), qui appelle recupererInfos(), tu utilises déjà fgets pour lire une ligne (à condition que tu déclares ta variable, bien sur). Alors, il faut choisir où tu mets le code qui lit une ligne du fichier texte.
Là, ton code ne te permet pas de lire le fichier ligne par ligne. Essaye déjà de faire cela (sans *aucun* warning ni erreur) :
1- ouvrir le fichier
2- lire une ligne du fichier dans une chaîne de caractères C
3- afficher cette chaîne de caractères C
4- boucler sur 2 tant que le fichier contient des lignes
5- fermer le fichier
Poste ton code lorsque tu auras fait cela. Ensuite, tu pourras t'attaquer au traitement de chaque ligne.
3.
Enfin, dans ton énoncé de départ (c'est un devoir ?) tu indiquais que tu devais renseigner "une structure avec les informations". Là ta structure (
struct) a disparu.
Si tu fais ce programme sans contraintes particulières, il est important de savoir quel est l'objectif et les fonctionnalités que tu attends de ton programme, et de décider en fonction de cela de la façon dont tu vas l'implémenter.
Par contre, si c'est un devoir et qu'on te demande d'utiliser des structures... ben... il faudra que tu les utilises.. non ?
Mais là on anticipe sur quelque chose qui dépasse la première étape, on verra cela quand tu auras produit un code correspondant à la fonctionnalité décrite en 2.
Dal
Bonjour DAL,
Merci de vous avoir intéressé a mon soucis.
J'utilise Code Blocks et ce dernier se lançait sans me signaler ces erreurs.
Peut être s'agit il d'un problème de paramétrage chez moi.
Je vous rassure, il ne s'agit pas d'un devoir.
J'essaies de mette en place un petit logiciel pour mon association.
Le but est de basculer ces infos dans une structure, je l'ai omis ici afin de simplifier et retrouver plus facilement ou cela bogue.
Je retraite mon programme afin de limiter les erreurs et reviens vers vous.
Merci encore.
Rhamm
Merci de vous avoir intéressé a mon soucis.
J'utilise Code Blocks et ce dernier se lançait sans me signaler ces erreurs.
Peut être s'agit il d'un problème de paramétrage chez moi.
Je vous rassure, il ne s'agit pas d'un devoir.
J'essaies de mette en place un petit logiciel pour mon association.
Le but est de basculer ces infos dans une structure, je l'ai omis ici afin de simplifier et retrouver plus facilement ou cela bogue.
Je retraite mon programme afin de limiter les erreurs et reviens vers vous.
Merci encore.
Rhamm
Si tu utilises Codeblocks, il y a de fortes chances que ton compilateur soit gcc.
Par défaut, tous les warnings devraient être activés. Tu peux vérifier la configuration des paramètres de gcc dans Project - Build options - Compiler settings - Compiler flags - la case "Enable all compiler warnings" correspondant à l'option -Wall devrait être cochée, si elle ne l'est pas, coche la. Mais cochée ou non, tu devrais avoir des erreurs (et aussi des warnings) qui s'affichent lorsque tu compiles, dans l'onglet "Build messages". Le fait que tu n'aies aucune erreur à la compilation est anormal.
Peux-tu donner un exemple de données contenues dans ton fichier ?
Si ce n'est pas un devoir, il y a des langages bien plus simples pour traiter du texte que le langage C.
Par exemple, Perl ou Python, où cela se fait en moins de 10 lignes.
Cela dit, tu n'as pas répondu sur ce que tu veux faire des données une fois splittées, c'est aussi en fonction de cela que tu dois décider quoi faire et comment.
Dal
Par défaut, tous les warnings devraient être activés. Tu peux vérifier la configuration des paramètres de gcc dans Project - Build options - Compiler settings - Compiler flags - la case "Enable all compiler warnings" correspondant à l'option -Wall devrait être cochée, si elle ne l'est pas, coche la. Mais cochée ou non, tu devrais avoir des erreurs (et aussi des warnings) qui s'affichent lorsque tu compiles, dans l'onglet "Build messages". Le fait que tu n'aies aucune erreur à la compilation est anormal.
Peux-tu donner un exemple de données contenues dans ton fichier ?
Si ce n'est pas un devoir, il y a des langages bien plus simples pour traiter du texte que le langage C.
Par exemple, Perl ou Python, où cela se fait en moins de 10 lignes.
Cela dit, tu n'as pas répondu sur ce que tu veux faire des données une fois splittées, c'est aussi en fonction de cela que tu dois décider quoi faire et comment.
Dal
en fait, selon la façon dont un champ vide va être représenté en csv, il est possible que strtok ne soit pas adapté (en particulier si un champ vide serait comme ceci ";;", strtok va passer à côté.
voilà un exemple n'utilisant pas strtok et fonctionnant sur un jeu de données avec 4 champs (donc 3 ; séparateurs selon le format standard, il n'y a pas de ; en fin de ligne) comme celui-ci :
en procédant comme cela :
donne à l'exécution le résultat suivant :
Dal
voilà un exemple n'utilisant pas strtok et fonctionnant sur un jeu de données avec 4 champs (donc 3 ; séparateurs selon le format standard, il n'y a pas de ; en fin de ligne) comme celui-ci :
nom;prenom;date_de_naissance;lieu_de_naissance
Einstein;Albert;14-03-1879;Ulm (Allemagne)
de Saint-Exupéry;Antoine;29-06-1900;Lyon
Baba;Orhum;;
Chaplin;Charlie;16-04-1889;Walworth (Royaume-Uni)
en procédant comme cela :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 256
#define MAX_CSV_RECORDS 1000
struct a_record {
char * lastname;
char * firstname;
char * birthdate;
char * place;
};
void split_csv_line(char * line, struct a_record * rec) {
char * cur;
int n = 0;
/* first field starts at beginning of the line */
rec->lastname = line;
/* count ; replace them by '\0' and locate the
* other fields */
cur = line;
while (cur[0]) {
if (cur[0] == ';') {
cur[0] = '\0';
n++;
if (n == 1) rec->firstname = cur + 1;
if (n == 2) rec->birthdate = cur + 1;
if (n == 3) rec->place = cur + 1;
}
cur++;
}
if (n != 3) {
printf("Error: wrong number of fields\n");
exit(1);
}
}
int main(void){
char filename[] = "data.csv";
struct a_record records[MAX_CSV_RECORDS];
char * line;
int rec_count = 0;
/* get data from file */
FILE * file = fopen(filename, "r" );
if (file) {
line = malloc(MAX_LINE_LENGTH);
while (fgets (line, MAX_LINE_LENGTH, file)) {
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
split_csv_line(line, &records[rec_count]);
line = malloc(MAX_LINE_LENGTH);
rec_count++;
if (rec_count > MAX_CSV_RECORDS) {
printf("Error: there are more than %d lines in %s\n",
MAX_CSV_RECORDS, filename);
exit(1);
}
}
fclose(file);
}
else {
perror(filename);
}
/* list data */
int n;
for (n = 0; n < rec_count; n++)
printf("l = %s\nf = %s\nb = %s\np = %s\n\n", records[n].lastname, records[n].firstname, records[n].birthdate, records[n].place);
/* free memory */
free(line);
for (n = 0; n < rec_count; n++)
free(records[n].lastname);
return 0;
}
donne à l'exécution le résultat suivant :
l = nom
f = prenom
b = date_de_naissance
p = lieu_de_naissance
l = Einstein
f = Albert
b = 14-03-1879
p = Ulm (Allemagne)
l = de Saint-Exupéry
f = Antoine
b = 29-06-1900
p = Lyon
l = Baba
f = Orhum
b =
p =
l = Chaplin
f = Charlie
b = 16-04-1889
p = Walworth (Royaume-Uni)
Dal
Bonjour Dal,
Mon fichier de base sera configuré de telle manière (c'est un exemple simplifié) :
nom;prenom;date_de_naissance;lieu_de_naissance;adresse
Il se peut qu'il y ait des champs vides.
Mais aussi des espaces a linterieur des champs. Ex : Rue de la Fontaine;
En fait je souhaiterais croiser ces infos avec un autre fichier.
1 fichier : Informations sur les bénévoles
2eme fichier : Les horaires - les couts - etc...
Par la suite je souhaiterais créer une application qui compilerait le tout dans un tableau.
Je ne sais pas si c'est possible mais je souhaite créer un identifiant commun entre les deux structures (des 2 fichiers) afin que les infos se rattachent.
Ex :
Fichier 1 : Identifiant;nom;prenom;date_de_naissance;lieu_de_naissance;adresse
Fihcier 2 : Identifiant;horaire;cout
Afin de faire des statistiques selon le nombre d heures par bénévoles et/ou le cout de chacun.
Je sais c'est ambitieux.
Concernant le langage choisi, je commence a apprendre grâce a des bouquins achetés et aux forums. je ne connais que le C.
Je vois que grâce a ton code, tu as répondus à une grande partie de ce que je recherche.
Mais comment faire si je ne connais pas le nombre de caractères par lignes et le nombre de lignes que contiendra mon fichier.
C'est pourquoi dans mon 1er code j'avais mis en place un compteur.
Mais apparemment celui-ci n 'était. pas pris en compte.
J'essaie d'adapter ton code en fonction de mon fichier et te donnerais le résultat.
Merci encore.
Rhamm.
Mon fichier de base sera configuré de telle manière (c'est un exemple simplifié) :
nom;prenom;date_de_naissance;lieu_de_naissance;adresse
Il se peut qu'il y ait des champs vides.
Mais aussi des espaces a linterieur des champs. Ex : Rue de la Fontaine;
En fait je souhaiterais croiser ces infos avec un autre fichier.
1 fichier : Informations sur les bénévoles
2eme fichier : Les horaires - les couts - etc...
Par la suite je souhaiterais créer une application qui compilerait le tout dans un tableau.
Je ne sais pas si c'est possible mais je souhaite créer un identifiant commun entre les deux structures (des 2 fichiers) afin que les infos se rattachent.
Ex :
Fichier 1 : Identifiant;nom;prenom;date_de_naissance;lieu_de_naissance;adresse
Fihcier 2 : Identifiant;horaire;cout
Afin de faire des statistiques selon le nombre d heures par bénévoles et/ou le cout de chacun.
Je sais c'est ambitieux.
Concernant le langage choisi, je commence a apprendre grâce a des bouquins achetés et aux forums. je ne connais que le C.
Je vois que grâce a ton code, tu as répondus à une grande partie de ce que je recherche.
Mais comment faire si je ne connais pas le nombre de caractères par lignes et le nombre de lignes que contiendra mon fichier.
C'est pourquoi dans mon 1er code j'avais mis en place un compteur.
Mais apparemment celui-ci n 'était. pas pris en compte.
J'essaie d'adapter ton code en fonction de mon fichier et te donnerais le résultat.
Merci encore.
Rhamm.
Qu'il y ait des espaces ou pas, le fonctionnement de mon code n'est pas affecté.
Pour simplifier le code, je ne suis pas parti sur de l'allocation dynamique totale.
Si tu ne connais pas la longueur des lignes, ni le nombre maximal d'enregistrements, tu peux allouer dynamiquement une taille, puis lorsque tu constates que tu atteins la limite, doubler la taille allouée, avec realloc.
C'est la stratégie de ton code en https://forums.commentcamarche.net/forum/affich-31708846-comment-lire-un-fichier-csv-avec-separateur-pour-structure#5 lignes 73 et suivantes (as-tu écrit ce code ?).
Pour la lecture de ligne, tu lis une ligne en mettant ta taille maximale avec fgets, et tu contrôles si ta ligne comporte \n ou pas(avec strchr). Si oui, tu as lu ta ligne en entier. Sinon, tu dois augmenter la taille du tampon, et continuer à lire à la suite.
Note que pour simplifier le code, je n'ai pas mis le contrôle de succès de l'allocation. Il faudra le faire dans un code en production.
Ce que tu veux faire, en fait, est une gestion de base de données.
Si j'étais toi, je mettrais ces données csv dans un système de gestion de bases de données pour faire des requêtes SQL dessus. Cela nécessite que tu apprennes SQL, mais tu t'économiseras de nombreuses heures de développement en C.
Si tu ne veux pas installer un serveur SQL (tel que MySQL ou PostgreSQL), tu peux utiliser un système de gestion de base de données sans serveur, comme SQLite : https://www.sqlite.org/index.html que tu peux, d'ailleurs, piloter en C si tu le souhaites (à la base, c'est une bibliothèque C), ou utiliser avec une interface, par exemple https://sqlitestudio.pl/ (qui te permettra d'importer directement des fichiers CSV d'ailleurs).
Dal
Pour simplifier le code, je ne suis pas parti sur de l'allocation dynamique totale.
Si tu ne connais pas la longueur des lignes, ni le nombre maximal d'enregistrements, tu peux allouer dynamiquement une taille, puis lorsque tu constates que tu atteins la limite, doubler la taille allouée, avec realloc.
C'est la stratégie de ton code en https://forums.commentcamarche.net/forum/affich-31708846-comment-lire-un-fichier-csv-avec-separateur-pour-structure#5 lignes 73 et suivantes (as-tu écrit ce code ?).
Pour la lecture de ligne, tu lis une ligne en mettant ta taille maximale avec fgets, et tu contrôles si ta ligne comporte \n ou pas(avec strchr). Si oui, tu as lu ta ligne en entier. Sinon, tu dois augmenter la taille du tampon, et continuer à lire à la suite.
Note que pour simplifier le code, je n'ai pas mis le contrôle de succès de l'allocation. Il faudra le faire dans un code en production.
Ce que tu veux faire, en fait, est une gestion de base de données.
Si j'étais toi, je mettrais ces données csv dans un système de gestion de bases de données pour faire des requêtes SQL dessus. Cela nécessite que tu apprennes SQL, mais tu t'économiseras de nombreuses heures de développement en C.
Si tu ne veux pas installer un serveur SQL (tel que MySQL ou PostgreSQL), tu peux utiliser un système de gestion de base de données sans serveur, comme SQLite : https://www.sqlite.org/index.html que tu peux, d'ailleurs, piloter en C si tu le souhaites (à la base, c'est une bibliothèque C), ou utiliser avec une interface, par exemple https://sqlitestudio.pl/ (qui te permettra d'importer directement des fichiers CSV d'ailleurs).
Dal
Bonjour Dal,
En effet il serait peut être plus sage de faire appel a une base de donnée.
Sqlite me semble être un bon début car je pourrais essayé de le piloter en C.
Je n 'ai plus qu'a trouver un tuto en français.
Le code que vous m'avez fourni ci-dessous est la réponse que je cherchais depuis quelques semaines. Cela va m'être très utile quant à la compréhension du C.
Je débute et ne maîtrise pas suffisamment ce langage.
Merci.
Rhamm
En effet il serait peut être plus sage de faire appel a une base de donnée.
Sqlite me semble être un bon début car je pourrais essayé de le piloter en C.
Je n 'ai plus qu'a trouver un tuto en français.
Le code que vous m'avez fourni ci-dessous est la réponse que je cherchais depuis quelques semaines. Cela va m'être très utile quant à la compréhension du C.
Je débute et ne maîtrise pas suffisamment ce langage.
Merci.
Rhamm
Tu as écrit un code de 261 lignes qui ne compile pas dès la 30ème ligne et qui renvoie 65 lignes d'erreurs et avertissements.
Ce n'est pas comme cela qu'on crée un programme. Dès que tu as écris quelques lignes, compile et teste. Dès que tu as écris quoi que ce soit de fonctionnel, compile, teste et vérifies en le fonctionnement. Tu n'attends d'avoir écrit pas loin de 300 lignes, pour ne pas savoir quoi en faire et le balancer sur un forum.
Ton code, qui ne compile pas, n'illustre pas ta question car il n'est pas limité à ta question (en fait les très nombreuses erreurs montrent que tu devrais te poser plein d'autres questions et les résoudre avant d'en arriver à celle que tu poses).
Ta question est, en résumé, comment faire en C pour séparer les champs d'une ligne de texte séparés par des ;
Une réponse est : tu peux te servir de strtok pour le faire : http://www.cplusplus.com/reference/cstring/strtok/
Pour lire des lignes de texte dans un fichier texte, j'utiliserais fgets, pas fread.
Je ne comprends pas ce que tu veux tester en écrivant des tests tels que , tu as des ` au lieu de ' pour délimiter un caractère, tu appelles une fonction dans main en omettant d'utiliser des parenthèses, tu mets des majuscules aux types, tu crées une fonction mais tu ne t'en sert pas dans ton code mais dans une déclaration de tableau (de nouveau sans parenthèses, mais que tu les mettes ou pas ce n'est pas la bonne façon de procéder), etc., etc.
Si tu dois stocker les éléments dans une structure, tu as besoin d'un tableau de structures, ou d'une liste chaînée de structures, vu que tu as plus d'une ligne à charger en mémoire. Si tu veux faire un tableau, comme tu sembles vouloir le faire, soit tu fais un tableau de taille statique avec une taille maximale, soit tu déclares un pointeur sur la structure et tu alloues avec malloc suffisamment de mémoire pour le nombre de structures à stocker.
Tu peux alors te servir de pour déterminer au préalable la mémoire dynamique nécessaire à partir du nombre de lignes (et donc de structures à stocker).
Dal