IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

code pour lecture de fichier


Sujet :

C

  1. #1
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut code pour lecture de fichier
    salut,

    Je cherche un code en C qui me permette d'ouvrir un fichier en accés séquentiel, de lire ligne à ligne et dès que je trouve une instruction \n, d'insérer la ligne précédente dans une table (base de données ORACLE).

    Si quelqu'un a une piste

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Bref, tu veux dire, insérer chaque ligne du fichier dans la base ?

    Je ne pourrais t'aider pour le code d'insertion en base, mais j'ai une question pour les lignes:
    Est-ce qu'elles ont une taille maximum ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    oui les lignes sont limitées à 86 caractères

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Dans ce cas, la partie "lecture des lignes" est plutôt facile: Il suffit de lire les lignes avec fgets()...

    Un code de ce genre (attention, je n'ai pas testé) devrait faire l'affaire...
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    /* Retourne 0 si OK, -1 si erreur. */
    int EnvoyerLigneEnBase(char const * ligne)
    {
    	/* ... */
    }
     
    /* Retourne 0 si OK, -1 si erreur. */
    int LireFichierOuvert(FILE *pIn)
    {
    	char buf[90];
     
    	/* fgets() retourne NULL en cas d'erreur */
    	while(fgets(buf, 90, pIn) != NULL)
    	{
    		/* Ici, buf contient une ligne terminée par un \n */
     
    		/* Suppression du \n (enfin, si tu veux) */
    		char * pLF = strchr(buf, '\n');
    		if(pLF != NULL)
    		{
    			/* \n trouvé: Tronque la chaîne juste avant */
    			*pLF = '\0';
    		}
    		else if(strlen(buf) == 90-1)
    		{
    			return -1; /* ERREUR: La ligne était trop longue. */
    		}
    		else
    		{
    			/* Pas de \n mais ligne pas trop longue:
    			   Ce doit être la dernière. */
    		}
     
    		/* Traitement de la ligne */
    		if( EnvoyerLigneEnBase(ligne) < 0 )
    			return -1;
    	}
    	return 0;
    }
     
    /* Retourne 0 si OK, -1 si erreur. */
    int LireFichier(char const *nomFich)
    {
    	FILE * pIn = fopen(nomFich, "r");
    	int ret = -1;
    	if(pIn != NULL)
    	{
    		puts("Lecture du fichier...");
    		ret = LireFichierOuvert(pIn);
    		fclose(pIn);
    	}
    	else
    		puts("Echec d'ouverture.");
    	return ret;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    Merci pour ton aide, mais je suis débutant en C, est-ce que tu pourrais si c'est possible commenter ton code en m'indiquant précisément les opérations décrites.

    Merci d'avance

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    D'accord, je vais commenter un peu plus, vérifier que le code compile et poster la version commentée.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    C'est super, merci encore

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Voici le code commenté. Il compile sans erreurs ni warnings, sauf la variable inutilisée dans la fonction vide.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    /* ===============================================================
       Inclusions de fichiers d'en-tête de la bibliothèque standard */
     
    #include <stdio.h>  /* Fonctions d'entrées/sorties (fichiers etc.) */
    #include <string.h> /* Fonctions sur les chaînes de caractères */
     
     
    /* =========================
       Fonctions du programme */
     
    /* --------------------------------------------------
       Fonction pour envoyer la ligne en base de données.
       Il n'y a rien dedans, puisque je ne sais pas comment on fait.
       
    Paramètres:
    	ligne : La ligne lue (c'est un pointeur const sur le premier caractère de la ligne)	
    Retourne 0 si OK, -1 si erreur. */
    int EnvoyerLigneEnBase(char const * ligne)
    {
    	/* ... */
    	return 0;
    }
     
     
    /* ----------------------------------------------------------------------------
       Fonction pour lire sur le fichier ouvert.
       La fonction lit chaque ligne du fichier pour son buffer de 90 caractères.
       Ensuite, elle cherche le caractère de retour à la ligne dedans,
       le supprime s'il est là (si les lignes sont bien limitées à 86 caractères, 
       il sera forcément là, sauf pour la dernière ligne) puis appelle
       la fonction EnvoyerLigneEnBase() sur la ligne lue.
     
    Paramètres:
    	pFichierIn : Le fichier ouvert (c'est un FILE*, on n'a pas besoin de savoir ce qu'il y a dedans)   
    Retourne 0 si OK, -1 si erreur. */
    int LireFichierOuvert(FILE *pFichierIn)
    {
    	/* Le tableau de 90 caractères: fgets() va y mettre la ligne lue du fichier. */
    	char bufLigne[90];
     
    	/* fgets() est la fonction standard de lecture d'une ligne dans un fichier ouvert.
    	   Elle retourne NULL en cas d'erreur.
    	   Si elle réussit à lire une ligne complet, le retour à la ligne (\n) sera dedans.
    	   Si la ligne est trop grande pour le buffer, elle sera tronquée avant. */
    	while(fgets(bufLigne, 90, pFichierIn) != NULL)
    	{
    		/* Ici, buf contient une ligne terminée par un \n */
     
    		/* Recherche du \n pour le supprimer:
    		   strchr() est la fonction standard de recherche d'un caractère dans une chaîne.
    		   Elle prend un pointeur de chaîne de caractères et un caractère en paramètre.
    		   Elle retourne l'adresse du caractère dans la chaîne, ou NULL si elle ne l'a pas trouvé. */
    		char * pLF = strchr(bufLigne, '\n');
     
    		/* Si on l'a trouvé, on le vire.
    		   Sinon, c'est soit une erreur, soit la dernière ligne. */
    		if(pLF != NULL)
    		{
    			/* \n trouvé: Tronque la chaîne juste avant */
    			*pLF = '\0';
    		}
    		else if(strlen(bufLigne) == 90-1)
    		{
    			/* strlen() donne la longueur d'une chaîne de caractère (sans le caractère nul à la fin).
    			   Si cette longueur est égale à la taille du buffer moins 1, c'est que le buffer est plein à ras bord. */
    			return -1; /* ERREUR: La ligne était trop longue. */
    		}
    		else
    		{
    			/* Pas de \n mais ligne pas trop longue:
    			   Ce doit être la dernière. */
     
    			/* On ne fait rien ici. */
    		}
     
    		/* Traitement de la ligne */
    		if( EnvoyerLigneEnBase(bufLigne) < 0 )
    			return -1;
    	}
    	return 0;
    }
     
     
    /* ----------------------------------------------------------------------------
       Fonction pour ouvrir un fichier et le lire:
       Cette fonction ouvre le fichier dont on lui passe le nom,
       elle obtient alors un pointeur de fichier ouvert.
       Alors elle appelle la fonciton LireFichierOuvert() sur ce pointeur.
     
    Paramètres:
    	nomFich: Nom du fichier à lire (c'est en fait un pointeur sur le premier caractère du nom)
    Retourne 0 si OK, -1 si erreur. */
    int LireFichier(char const *nomFich)
    {
    	/* Valeur qui sera retournée par la fonction.
    	   Si l'ouverture échoue, elle restera à -1 (erreur). */
    	int ret = -1;
    	/* Variable qui contiendra le pointeur de fichier ouvert, retourné par fopen() */
    	FILE * pFichier = NULL;
     
    	/* fopen() est la fonction standard pour ouvrir un fichier.
    	Elle retourne un pointeur de fichier ouvert, ou NULL si l'ouverture échoue. */
    	pFichier = fopen(nomFich, "r");
     
    	if(pFichier != NULL)
    	{
    		/* Le pointeur n'est pas NULL, l'ouverture a donc réussi. */
     
    		/* puts() : Une fonction standard toute bète pour afficher un message. */
    		puts("Lecture du fichier...");
     
    		ret = LireFichierOuvert(pFichier);
     
    		/* fclose() : Fonction pour fermer un fichier ouvert.
    		Il ne faut pas l'utiliser si le pointeur est NULL. */
    		fclose(pFichier);
    	}
    	else
    	{
    		/* Le pointeur est NULL, l'ouverture a échoué. */
     
    		puts("Echec d'ouverture.");
    	}
    	return ret;
    }
    Note: Ce code n'est pas un programme, puisqu'il n'y a pas de fonction main() : Il s'agit juste de trois fonctions pouvant être utilisées dans ton programme.

    J'ignore comment tu veux utiliser ces fonctions, mais le moyen le plus simple, c'est un main() contenant juste un appel à la fonction avec le chemin absolu de ton fichier (on peut faire plus pratique ensuite).
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(void)
    {
    	LireFichier("C:\\UnDossier\\UnFichier.txt");
    	return 0;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    En fait, j'ai plusieurs fichiers sous unix, qui permettent l'édition de factures, d'accusés, de devis... le tout en mode caractère bien évidemment.

    nous sommes en train de migrer la solution en mode web. Pour cela on utilise des outils (Forms, report...).

    Le but de l'opération est de lire ces fichiers d'édition, et d'insérer chaque ligne dans une table de la base de données, ce qui nous permettra à partir de cette table, de réinjecter les lignes dans un report.

    Cà a pas l'air simple en le disant et encore moins en réalité.

    D'où ma demande d'aujourd'hui. Je ne sais pas si tu peux affiner ta réponse selon ce qui je viens de t'exposer. C'est vrai que ça me serait très utile, vu que moi je suis plutôt spécialiste de JAVA et du développement web...

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Eh bien, il y a plusieurs axes de développement.
    • Si chaque ligne du fichier correspond à une ligne en base, elle contiendra sûrement plusieurs champs. Ces champs, il faudra les séparer, il y a plusieurs moyens pour cela. Si l'on retire le const dans le prototype de la fonction void EnvoyerLigneEnBase(char const * ligne), on s'ouvre un moyen supplémentaire de décomposer la ligne à peu de frais.
    • On peut aussi s'orienter vers la façon d'utiliser la fonction. Par exemple, faire du programme C un programme en ligne de commande qui prendrait le chemin du fichier en paramètre, au lieu de l'avoir directement dans son code.

    PS: Je rappelle que je n'y connais rien aux communications avec base de données en C. Mais quelqu'un d'autre sait sûrement quelque chose...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    Je pencherais plutôt pour la première solution. Si je t'ai bien suivi, il suffit de remplacer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int EnvoyerLigneEnBase(char const* ligne)
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int EnvoyerLigneEnBase(char * ligne)

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Ce ne sont pas deux solutions au même problème, ce sont deux axes d'approche différents (et on peut faire les deux, et on finira sûrement par faire les deux).

    Le remplacement que tu viens de décrire est bien celui dont je parlais, mais il n'est pas lui-même le moyen: Ce remplacement n'est qu'un outil permettant d'utiliser un meilleur outil à peu de frais.
    Supposons que chaque ligne contienne des valeurs séparées par des points-virgules. Par exemple, pour une table à trois colonnes numériques:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    42;23;129987
    968;35;79
    (la suite arrive)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Pour ceci, la première chose à faire est de séparer les champs: Comme on n'a pas de vérification compliquée à faire (comme vérifier qu'un ; n'est pas dans une chaîne) puisqu'il n'y a pas de chaîne, nous pouvons utiliser directement la fonction standard strtok() pour la séparer selon les points-virgules.
    Note: Cette fonction a certains inconvénients et est déconseillée quand il y a une alternative disponible, notamment strtok_r(). Mais il n'y a pas toujours d'alternative, et les inconvénients ne se manifesteront pas dans notre petit programme.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    int EnvoyerLigneEnBase(char * ligne)
    {
    	long valeur1, valeur2, valeur3;
    	/* La fonction strtok() modifie la chaîne passée en paramètre
    	   pour la couper en morceaux. C'est pourquoi il faut
    	   que EnvoyerLigneEnBase() aie le droit de modifier la ligne,
    	   donc on ne pourrait pas utiliser directement strtok() sur ligne
    	   si le pointeur était const. */
    	char * morceau = NULL;
    	char * finNombre;
     
    	/* On saute les lignes vides sans renvoyer d'erreur */
    	if(strlen(ligne)==0)
    		return 0;
     
    	morceau = strtok(ligne, ";");
    	/* On sait que la chaîne doit être en trois morceaux.
    	   Alors, on va renvoyer une erreur si un morceau manque. */
    	if(morceau == NULL)
    		return -1;
    	/* La fonction strtol() convertit une chaîne en valeur numérique
    	   Elle retourne l'adresse de fin dans son premier paramètre,
    	   ce qui est utile pour vérifier. */
    	valeur1 = strtol(morceau, &finNombre, 10);
    	if(finNombre==NULL || *finNombre!='\0')
    	{
    		/* Erreur: La conversion a échoué ou bien s'est arrêtée
    		   avant la fin du morceau. */
    		return -1;
    	}
     
    	/* Second morceau, seconde valeur. */
    	morceau = strtok(NULL, ";");
    	if(morceau == NULL)
    		return -1;
    	valeur2 = strtol(morceau, &finNombre, 10);
    	if(finNombre==NULL || *finNombre!='\0')
    		return -1;
     
    	/* Troisième morceau, seconde valeur. */
    	morceau = strtok(NULL, ";");
    	if(morceau == NULL)
    		return -1;
    	valeur3 = strtol(morceau, &finNombre, 10);
    	if(finNombre==NULL || *finNombre!='\0')
    		return -1;
     
    	/* On vérifie qu'il n'y a pas de Quatrième morceau. */
    	morceau = strtok(NULL, ";");
    	if(morceau != NULL) /* C'est un != cette fois*/
    		return -1;
     
     
    	/* Maintenant, on a complètement lu la chaîne,
    	   Et on a nos trois valeurs.
    	   C'est là qu'il faut les envoyer à la base de données
    	   (mais j'ignore comment) */
    	/* ... */
     
    	return 0;
    }
    Note: strtol() est déclarée dans le fichier d'en-tête <stdlib.h>, donc il faut rajouter en tête de fichier source:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    #include <stdlib.h> /* Principales fonctions de biblio standard. */
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gege87270 Voir le message
    En fait, j'ai plusieurs fichiers sous unix, qui permettent l'édition de factures, d'accusés, de devis... le tout en mode caractère bien évidemment.

    nous sommes en train de migrer la solution en mode web. Pour cela on utilise des outils (Forms, report...).

    Le but de l'opération est de lire ces fichiers d'édition, et d'insérer chaque ligne dans une table de la base de données, ce qui nous permettra à partir de cette table, de réinjecter les lignes dans un report.

    Cà a pas l'air simple en le disant et encore moins en réalité.

    D'où ma demande d'aujourd'hui. Je ne sais pas si tu peux affiner ta réponse selon ce qui je viens de t'exposer. C'est vrai que ça me serait très utile, vu que moi je suis plutôt spécialiste de JAVA et du développement web...
    Si je comprends bien, il s'agit d'une opération de migration unique (on migre puis on bosse ensuite dans le système migré) alors pourquoi le faire en C ? Le C est très rapide mais très très bas niveau (faut réserver la mémoire, regarder si on a tout lu, etc).

    Tu pourrais t'orienter vers des langages plus simples comme le shell
    Exemple du même programme écrit en shell

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/bin/sh
     
    # Mise en mémoire du fichier dans le buffer n° 3
    exec 3<UnFichier.txt
     
    # Lecture du buffer 3 (le fichier) ligne par ligne
    while read ligne 0<&3
    do
        # Découpage de la ligne pour avoir les 3 valeurs
        valeur1=`echo $ligne |cut -f1 -d;`
        valeur2=`echo $ligne |cut -f2 -d;`
        valeur3=`echo $ligne |cut -f3 -d;`
     
        # Si une des valeurs est vides
        if test -z "$valeur1" -o -z "$valeur2" -o -z "$valeur3"
        then
             # Truc à faire ici si on tombe dans ce cas
        fi
     
        # Insérer les 3 valeurs dans la bdd
        insert($valeur1, $valeur2, $valeur3)
    done

    Si le fichier est très gros, cela peut être long. Tu peux essayer Python qui est assez souple et hyper rapide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #!/bin/env python
     
    # Ouverture du fichier
    file=open("UnFichier.txt", "r")
     
    # Lecture du fichier ligne à ligne
    while True:
        ligne=file.readline()
     
        # Si la ligne est vide => fin de fichier => sortie de boucle
        if "$ligne" == "" : break
     
        # Découpage de la ligne pour avoir les 3 valeurs
        valeurs=ligne.split(";")
     
        # Si le nb de valeurs n'est pas 3
        if len(valeurs) != 3:
             # Truc à faire ici si on tombe dans ce cas
     
        # Insérer les 3 valeurs dans la bdd
        insert(int(valeurs[0]), int(valeurs[1]), int(valeurs[2]))
     
    # Fermeture fichier
    file.close()
    Le C c'est chouette mais quand on commence à se prendre la tête avec toutes les contraintes, ça va bien un temps...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    J'avoue que j'ai mal à suivre. Je ne vois pas comment je pourrais utiliser ton exemple. Moi le fichier que je lis est un fichier texte qui représente une édition papier.

    Par exemple :

    -----------------------------------------------------------------
    Le 23/10/2007
    Limoges,
    Code client : Xp00014

    Facture
    _________________________________________________________
    Ref | Désignation |Prix HT | Prix TTC |
    _________________________________________________________
    a |xxxxxxxxxxxxxxxxxxxx |10.25 |15.64 |


    _________________________________________________________
    Total : 15.64
    -----------------------------------------------------------------

    Ce que je veux c'est lire ce fichier ligne à ligne et dès que je trouve un\n, (saut de ligne), je copie la ligne dans ma table et ainsi de suite jusqu'à la fin du fichier.

  16. #16
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    je crois que j'ai répondu en même temps que toi. Mon dernier post concerné ton post précedent.

    Je suis intéressé par le shell dont tu m'as parlé..

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Ce fichier texte me semble trop compliqué pour une analyse aussi simple.

    Le fichier, tu cherches à le mettre en base sous quel format exactement ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    Sous Oracle, j'ai créé une table (edit_pdf) avec 3 champs

    pdf_proc : number (qui contiendra le n° de session utilisateur) variable proc dans mon code.

    pdf_nligne : number (qui contiendra le n° de ligne de la ligne récupérée dans le fichier)

    pdf_ligne : varchar(85) (qui contiendra le contenu de la ligne)

    le but étant de lire le fichier en accès séquentiel (ligne à ligne) et dès que l'on trouve un \n (retour à la ligne), on copie la ligne (concaténation si plusieurs éléments), dans la table edit_pdf. Je pense que cette partie intégration doit se faire via des requêtes sql.

    J'ai déjà mis en place un shell avec awk qui me permet de retraité une première fois les programmes .pc (ajout, suppression, modification de ligne). Cette partie fonctionne très bien. J'avais envisagé de mettre en place des structures de contrôle (via des if) pour pouvoir faire le traitement qui m'intéresse, mais sur des codes de plus de 3000 lignes, c'est un travail fastidieux et on n'est pas à l'abrit d'un oubli.

    C'est pourquoi je me suis tourné vers cette lecture séquentielle, qui me parait être la meilleure solution.

  19. #19
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Ah OK, donc c'est plus simple que je le pensais: C'est vraiement chaque ligne qui est envoyée en tant que texte brut dans la base.
    Il n'y a donc pas d'histoires de séparation en champs, etc. donc tu peux oublier mes posts #12 et #13.
    Et le pointeur de la fonction EnvoyerLigneEnBase() peut redevenir const.

    Mais cela ne nous dit pas comment, en C, se connecter à une base de données Oracle et y insérer une ligne dans une table.
    Toutefois, cela nous laisse la place à des améliorations du code:
    • La variable proc doit être connue dans le programme de lecture séquentielle. Cela pourra être un paramètre en ligne de commande, nous reviendrons dessus plus tard. Ce qui est sûr, c'est qu'il faudra que la fonction EnvoyerLigneEnBase() le connaisse. Nous allons donc lui rajouter un paramètre, qui sera passé directement à travers les fonctions LireFichier() et LireFichierOuvert(). Ce paramètre sera un pointeur générique, comme on ne sait pas encore quoi passer.
      Code C : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      int EnvoyerLigneEnBase(char const * ligne, void * autre)
      {
      	...
      }
       
      int LireFichierOuvert(FILE *pFichierIn, void * autre)
      {
      	...
      		if( EnvoyerLigneEnBase(bufLigne, autre) < 0 )
      			return -1;
      	...
      }
       
      int LireFichier(char const *nomFich, void * autre)
      {
      	...
      		ret = LireFichierOuvert(pFichier, autre);
      	...
      }
    • L'autre amélioration est le numéro de ligne: Nous ajouterons un comptage de lignes dans la fonction LireFichierOuvert(), et un troisième paramètre à la fonction EnvoyerLigneEnBase().
      Code C : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      int EnvoyerLigneEnBase(char const * ligne, int num, void * autre)
      {
      	...
      }
       
      int LireFichierOuvert(FILE *pFichierIn, void * autre)
      {
      	/* Le tableau de 90 caractères: fgets() va y mettre la ligne lue du fichier. */
      	char bufLigne[90];
      	int numLigne = 1;
       
      	/* fgets() est la fonction standard de lecture d'une ligne dans un fichier ouvert.
      	   Elle retourne NULL en cas d'erreur.
      	   Si elle réussit à lire une ligne complet, le retour à la ligne (\n) sera dedans.
      	   Si la ligne est trop grande pour le buffer, elle sera tronquée avant. */
      	while(fgets(bufLigne, 90, pFichierIn) != NULL)
      	{
      		/* Ici, buf contient une ligne terminée par un \n */
       
      		/* Recherche du \n pour le supprimer:
      		   strchr() est la fonction standard de recherche d'un caractère dans une chaîne.
      		   Elle prend un pointeur de chaîne de caractères et un caractère en paramètre.
      		   Elle retourne l'adresse du caractère dans la chaîne, ou NULL si elle ne l'a pas trouvé. */
      		char * pLF = strchr(bufLigne, '\n');
       
      		/* Si on l'a trouvé, on le vire.
      		   Sinon, c'est soit une erreur, soit la dernière ligne. */
      		if(pLF != NULL)
      		{
      			/* \n trouvé: Tronque la chaîne juste avant */
      			*pLF = '\0';
      		}
      		else if(strlen(bufLigne) == 90-1)
      		{
      			/* strlen() donne la longueur d'une chaîne de caractère (sans le caractère nul à la fin).
      			   Si cette longueur est égale à la taille du buffer moins 1, c'est que le buffer est plein à ras bord. */
      			return -1; /* ERREUR: La ligne était trop longue. */
      		}
      		else
      		{
      			/* Pas de \n mais ligne pas trop longue:
      			   Ce doit être la dernière. */
       
      			/* On ne fait rien ici. */
      		}
       
      		/* Traitement de la ligne */
      		if( EnvoyerLigneEnBase(bufLigne, numLigne, autre) < 0 )
      			return -1;
      		numLigne++;
      	}
      	return 0;
      }

    Note: Je n'ai pas testé ni essayé de compiler, mais c'est l'idée générale.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  20. #20
    Membre confirmé Avatar de gege87270
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    224
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Mai 2007
    Messages : 224
    Par défaut
    Ok, on avance,

    Je vais regarder ça.

    A titre d'info, voilà le bout de code en pro*C pour se connecter à une base Oracle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /* -------------------- debut programme ---------------------------------- */
    main(argc,argv)
    .
    .
    .
    char *zTmp;
    .
    .
    .
    /* -------------------- connexion base ORACLE --------------------------- */
    zTmp=getenv("LOGINAME");
    if(zTmp) strcpy(CUser.arr,zTmp);
    else strcpy(CUser.arr,"00000001");
    setLen(CUser);
    EXEC SQL CONNECT :CUser IDENTIFIED BY :CUser;
    printf("Execution programme <%s> en cours....\n"
    ,argv[0]);
    

Discussions similaires

  1. Code pour récupérer un fichier
    Par Senki dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 21/07/2007, 00h44
  2. difference entre 2 codes pour lire un fichier svp.
    Par Slumpy dans le forum VB.NET
    Réponses: 2
    Dernier message: 10/05/2007, 10h11
  3. Réponses: 3
    Dernier message: 20/11/2006, 17h48
  4. Réponses: 2
    Dernier message: 08/11/2006, 20h57
  5. code pour enregistré un fichier sous different nom
    Par france38 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 28/10/2006, 13h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo