Ecrire totalité des resultats d'un programme dans un fichier en C

Ecrire totalité des resultats d'un programme dans un fichier en C - C - Programmation

Marsh Posté le 09-12-2015 à 15:19:12    

Bonjour, J'ai un programme principal de plus de 600 lignes de code. Je souhaite obtenir les résultats de mon programme dans unn fichier mais avoir toujours ces derniers dans ma console.
Y a-t'il un moyen de le faire sans écrire dans le progrmame à chaque fois que je fais un printf(), de faire fprintf() ou un gets() ?
J'ai essayé de faire en executant mon programme la commande suivant  

Code :
  1. ./mon_programme fichier_test.txt > resultat.txt


Il y a bien la création d'un fichier resultat.txt mais rien est écrit dedans.
 
Quelqu'un pourrait-i m'aider ?
 
Je vous joins mon programme qui se lit via un fichier de structure et un fichier de fonction et qui est incrémenté par un fichier texte de données.  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "serie4_functions.h"
  5. int choix = 0;
  6. char choix2;
  7. PERSONNE* nom_person;
  8. PERSONNE* liste = NULL;
  9. char tab_nom [30];
  10. int main ()
  11. {
  12. int choix;
  13. char choix2;
  14. PERSONNE* nom_person;
  15. PERSONNE* liste = NULL;
  16. char tab_nom [30];
  17. do {
  18. printf("1-Insérer une personne dans la liste.\n" );
  19. printf("2-Afficher les personnes dans la liste.\n" );
  20. printf("3-Rechercher une personne dans la liste.\n" );
  21. printf("4-Supprimer une personne dans la liste.\n" );
  22. printf("5-Quitter le programme.\n" );
  23. scanf("%d", &choix);
  24. switch (choix) {
  25. case 1 : {
  26.  do {
  27.    printf("INSERER UNE PERSONNE DANS LA LISTE.\n" );
  28.    printf("***********************************\n" );
  29.    nom_person = AllouePersonne();
  30.    SaisiePersonne(nom_person);
  31.    liste = InserePersonne(liste, nom_person);
  32.    printf("\n\nSouhaitez-vous saisir des nouvelles personnes dans la liste (o ou n)?\n" );
  33.    getchar();
  34.    scanf("%c", &choix2);
  35.  }while (choix2 != 'n');
  36. }break;
  37. case 2 : {
  38.    printf("AFFICHER LES PERSONNES DE LA LISTE.\n" );
  39.    printf("***********************************\n" );
  40.    AfficherPersonnes(liste);
  41. }break;
  42. case 3 : {
  43.  printf("RECHERCHER UNE PERSONNE DE LA LISTE.\n" );
  44.  printf("***********************************\n" );
  45.  printf("\n\n Veuillez saisir le nom de la personne recherchée dans la liste.\n" );
  46.         scanf("%s", tab_nom);
  47.  nom_person = RecherchePersonne(liste,tab_nom);
  48.  AfficherUnePersonne(nom_person);
  49. }break;
  50. case 4 : {
  51.  printf("SUPPRIMER UNE PERSONNE DE LA LISTE.\n" );
  52.  printf("***********************************\n" );
  53.  printf("\n\n Veuillez saisir le nom de la personne à supprimer dans la liste.\n" );
  54.  scanf("%s", tab_nom);
  55.  nom_person = RecherchePersonne(liste,tab_nom);
  56.  liste = SupprimePersonne(liste,nom_person);
  57.  AfficherPersonnes(liste);
  58. }break;
  59. case 5 : printf("Au revoir !!!!!!\n" );break;
  60. default : ("Veuillez saisir une valeur entre 1 et 5.\n" );
  61. }
  62. }while (choix != 5);
  63. return 0;
  64. }
  65. FICHIER serie4_fonctions.c
  66. #include<stdio.h>
  67. #include<string.h>
  68. #include<stdlib.h>
  69. #include "serie4_structures.h"
  70. PERSONNE* AllouePersonne()
  71. {
  72.   PERSONNE *pers=(PERSONNE*)malloc(sizeof(PERSONNE)) ;
  73.   if( pers==NULL )
  74.  printf("Memory allocation error in AllouePersonne()\n" ) ;
  75.   else
  76.     {
  77.       pers->nom=NULL ;
  78.       pers->suivant=NULL ;
  79.     }
  80.   return pers ;
  81. }
  82. char* SaisieNom()
  83. {
  84. char* nom=NULL ;
  85. char temp[100] ;
  86. int Nbchar=0, compt=0 ;
  87.     scanf("%s",temp);
  88. Nbchar=strlen(temp) ;
  89. nom=(char*)malloc(Nbchar*sizeof(char)) ;
  90. if(nom==NULL) printf("Memory Allocation Error in SaisieNom\n" ) ;
  91. else
  92.   {
  93.     for (compt=0 ;compt<=Nbchar ;compt++) nom[compt]=temp[compt] ;
  94.   }
  95. return nom ;
  96. }
  97. void SaisiePersonne(PERSONNE *pers)
  98. {
  99.   int compt=0 ;
  100.   if(pers==NULL)
  101. {
  102. printf("No Memory Allocation in SaisiePersonne()\n" ) ; }
  103. else {
  104. printf("\nNom ? (<100 charac.) " ) ; pers->nom=SaisieNom() ;
  105. printf("\nTelephone ? (10 chiffres)" ) ; scanf("%s",pers->telephone);
  106. } }
  107. PERSONNE *RecherchePersonne(PERSONNE *tete, char*nom)
  108. {
  109.      PERSONNE *current =tete;
  110.      while(current !=NULL && strcmp(current->nom,nom)!=0)
  111.      {
  112.            current=current->suivant ;
  113.      }
  114.      return current ;
  115. }
  116. PERSONNE *InserePersonne(PERSONNE *tete, PERSONNE *pers)
  117. {
  118.   PERSONNE *current=tete, *prec=NULL ;
  119.   if (tete==NULL) return pers ;
  120.   if (pers==NULL) return tete ;
  121.   if (strcmp(pers->nom,tete->nom)<0)
  122.     {pers->suivant=tete ;return pers ;}
  123.  
  124.   while(current->suivant !=NULL && strcmp(pers->nom,current->nom)>0)
  125.    {
  126.    prec=current ;current=current->suivant ;
  127.    }
  128.    
  129.   if (strcmp(pers->nom,current->nom)<0){
  130.       prec->suivant=pers ; pers->suivant=current ;
  131. }
  132.   else if (strcmp(pers->nom,current->nom)>0)
  133.    {
  134.     current->suivant=pers ;
  135. }
  136.   return tete ;
  137. }
  138. void LiberePersonne(PERSONNE *pers)
  139. {
  140.   free(pers->nom) ;
  141.   free(pers) ;
  142. }
  143. void AfficherUnePersonne(PERSONNE *p)
  144. {
  145. printf("---------\n" );
  146. if(p==NULL) {printf("Elt NULL" );}
  147. else {
  148.  printf("Nom: %s\n",p->nom);
  149.         printf("Telephone: %s\n",p->telephone);
  150. }
  151. printf("---------\n" );
  152. }
  153. void AfficherPersonnes(PERSONNE *tete)
  154. {
  155. PERSONNE  *current=tete ;
  156.     if(current ==NULL) {
  157.  printf("---------\n" );
  158.      printf("Liste vide" );
  159.  printf("---------\n" );
  160.     }
  161.    
  162.     while(current !=NULL)
  163.        {
  164.  printf("---------\n" );
  165.        printf("Nom: %s\n",current->nom);
  166.         printf("Telephone: %s\n",current->telephone);
  167.  current=current->suivant;
  168. printf("---------\n" );
  169.  }
  170. }
  171. PERSONNE *SupprimePersonne(PERSONNE *tete, PERSONNE *pers)
  172. {
  173.   PERSONNE *prec=NULL, *current=tete ;
  174.   if (tete==NULL || pers==NULL) return tete ;
  175.   if (tete==pers)
  176.      tete=tete->suivant ;
  177.   else
  178.   {
  179.      while(current !=NULL && current !=pers)
  180.        {prec=current ;current=current->suivant ;}
  181.      if(current !=NULL)
  182.        prec->suivant=current->suivant ;
  183.   }
  184.   LiberePersonne(pers) ; pers=NULL ;
  185.   return tete ;
  186. }
  187. void SupprimeListePersonne(PERSONNE *tete)
  188. {
  189.   while(tete !=NULL)
  190.      {tete=SupprimePersonne(tete,tete) ;}
  191. }
  192. FICHIER serie4_fonctions.h
  193. #include "serie4_structures.h"
  194. PERSONNE* AllouePersonne();
  195. char* SaisieNom();
  196. void SaisiePersonne(PERSONNE *pers);
  197. void AfficherUnePersonne(PERSONNE *p);
  198. void AfficherPersonnes(PERSONNE *tete);
  199. PERSONNE *RecherchePersonne(PERSONNE *tete, char*nom);
  200. PERSONNE *InserePersonne(PERSONNE *tete, PERSONNE *pers);
  201. PERSONNE *SupprimePersonne(PERSONNE *tete, PERSONNE *pers);
  202. void SupprimeListePersonne(PERSONNE *tete);
  203. FICHIER serie4_structure.h
  204. typedef struct personne
  205. {
  206.   char *nom ;
  207.   char telephone[10] ;
  208.   struct personne *suivant ;
  209. } PERSONNE ;
  210. typedef struct annuaire
  211. {
  212.   PERSONNE **tab ;
  213.   int Max ;
  214.   int Nb ;
  215. } ANNUAIRE ;


Reply

Marsh Posté le 09-12-2015 à 15:19:12   

Reply

Marsh Posté le 09-12-2015 à 15:21:13    

Solution ultra simpliste : remplacer tous les appels à printf() par une méthode à toi qui appelle elle même printf ET fait ton écriture sur le disque ? ;)


---------------
Topic .Net - C# @ Prog
Reply

Marsh Posté le 09-12-2015 à 15:41:21    

Si tu es sous unix/linux/OSX, tee est ton ami:
$ program [arguments...] 2>&1 | tee outfile
Et pour windows, utiliser un port de tee:
wintee: https://code.google.com/p/wintee/
le tee des unix utilities: http://unxutils.sourceforge.net/
 
A+,


Message édité par gilou le 09-12-2015 à 15:41:53

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-12-2015 à 15:43:36    

Bonjour ! Si vous êtes sous UNIX/Linux, la commande "script" peut être intéressante, ou alors la commande tee.
 
Bonne continuation !
 
Edit : Grillé par gilou :)


Message édité par Farian le 09-12-2015 à 15:44:56
Reply

Marsh Posté le 09-12-2015 à 15:46:21    

Note que si tu veux vraiment faire une trace complète de ton programme, il va falloir aussi suivre les input utilisateurs, et donc ça ne marchera pas aussi simplement.  
Il va te falloir avoir un flag (log on/off) et un fichier de log, et une copie dans le fichier de sortie de tous les outputs et tous les inputs.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-12-2015 à 16:21:59    

Les sorties sont souvent bufferisées. Donc, elles ne sont écrites qu'au bout d'un certain nombre d'octets, ou à la fin normale d'un programme.
Pour avoir des traces, il recommandé de vider le cache de temps en temps avec

fflush(stdout);


 
Sinon, un rapide coup d'oeil me fait percevoir un gros problème classique de borne dans les lignes :

Nbchar=strlen(temp) ;
nom=(char*)malloc(Nbchar*sizeof(char)) ;
if(nom==NULL) printf("Memory Allocation Error in SaisieNom\n" ) ;
else
  {
    for (compt=0 ;compt<=Nbchar ;compt++) nom[compt]=temp[compt] ;
  }


En effet, dans une boucle for, on met généralement une relation inférieure dans la partie médiane, mais très très très rarement une relation inférieure ou égale, car souvent ça fait dépasser la limite, et c'est ce qui se passe ici. Par ailleurs, quand on fait une allocation pour une chaine, d'habitude on réserve un octet de plus que la longueur pour avoir la place de mettre le zéro binaire de fin de chaine. Ici, aucune place n'est prévue pour le zéro binaire de fin de chaine, et c'est la fuite mémoire assurée, le plantage typique du newbie.

Reply

Marsh Posté le 09-12-2015 à 21:41:03    

Bonsoir à tous, merci pour vos conseils mais hélas, je suis débutante dans le domaine et il y a des commentaires que j'ai du mal à comprendre. (trop abstrait et compliqué pour moi!!!!!!!!!).
Le seul que j'ai un peu compris est le premier de gilou. J'ai donc essayé la commande suivante  
./mon_programme [arguments] 2&1 | tee outfile
mais la console ne me propose pas le menu et donc rien ne se passe. Si je tape sur une lettre le menu de mon programme défile en boucle. Après avoir quitter le programme, je visualise dans mon dossier outfile le menu ecrit en boucle.
Comment avoir dans la console mon programme et les différents menus tout en redirigeant les résultats obtenus dans la console aussi.
Encore navrée de ne pas comprendre tous les conseils donnés.
Bonne soirée.
Axelle

Reply

Marsh Posté le 09-12-2015 à 22:23:22    

Donc si je comprends bien, tu as essayé
./mon_programme fichier_test.txt 2>&1 | tee resultat.txt
C'est bien cela?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-12-2015 à 23:19:02    

Oui c'est cela que j'ai tapé mais j'ai joins dans mon premier post un mauvais programme.
voici une partie de mon programme correct. Celui -ci fait appel en argument a un fichier-test.txt.
Désolée pour l'erreur
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include "affiche_tableau.h"
  6. #include "creer_etat.h"
  7. #include "decroissant.h"
  8. /* DECLARATION DES VARIABLES GENERALES */
  9. int main(int argc, char** argv)
  10. {
  11. int i, j, k, g, s, K;
  12. int choixf, choix1, choix2, choix1_b, choix2_a;
  13. FILE* milieu_marin;
  14. milieu_marin = fopen (argv[1],"r" );
  15. EI* etat=(EI*)malloc(sizeof(EI));
  16. creer_etat(etat, milieu_marin);
  17. FILE* f_resultat;
  18. char nom_fichier[30];
  19. /* Question 2a : simulation avec k itérations */
  20. int abondances_k[etat->nb_sp+1];
  21. double Bio_tot_k = 0;
  22. float Cout_tot_k = 0;
  23. int nvel_abondances [etat->nb_sp+1];
  24. float fact;
  25. double Nvel_bio_tot;
  26. float Nvel_cout_tot, cout_mini;
  27. int espece_choisie;
  28. double Bio_tot_finale = 0;
  29. float Cout_tot_finale = 0;
  30. int cpt_sp_disp = 0;
  31. /* Question 2b : évolution historique */
  32. HIST* p = NULL;
  33. HIST* temp =NULL;
  34. HIST* historique = NULL;
  35. /* Question 2c : liste décroissante des espèces les plus choisies */
  36. int tab_sp[etat->nb_sp+1];
  37. CE* listeSP = NULL;
  38. /* Question 2d : liste décroissante des espèces les plus choisies avec un modèle aléatoire */
  39. int abondances_ka[etat->nb_sp+1];
  40. int tab_sp_a[etat->nb_sp+1];
  41. CE* listeSP_a = NULL;
  42. /* Question 2e : simulation avec effet de la sur-pêche */
  43. int abondances_k6[etat->nb_sp+1];
  44. int tab_sp_6 [etat->nb_sp+1];
  45. CE* listeSP_6 = NULL;
  46. int choix2_6_A, ab_max, ab_min;
  47. /* Question 3 : 100 simulations puis statistiques */
  48. int abondances_s[etat->nb_sp];
  49. float Bio_tot_s = 0;
  50. float Cout_tot_s = 0;
  51. double moyenne [etat->nb_sp+1];
  52. double variance [etat->nb_sp+1];
  53. double abondances_s_tab[etat->nb_sp+1][100];
  54. double max [etat->nb_sp+1];
  55. double min [etat->nb_sp+1];
  56. /* INITIALISATION */
  57. initia0_tab_int(tab_sp, etat->nb_sp+1);
  58. initia0_tab_int(tab_sp_a, etat->nb_sp+1);
  59. initia0_tab_int(tab_sp_6, etat->nb_sp+1);
  60. initia0_tab_double(moyenne, etat->nb_sp+1);
  61. initia0_tab_double(variance, etat->nb_sp+1);
  62. initia0_tab_double(max, etat->nb_sp+1);
  63. initia999_tab_double(min, etat->nb_sp+1);
  64. srand(time(NULL));
  65. /*CALCULS DES VALEURS TOTALES AVANT DEROULEMENT DU MENU */
  66. for (i=1; i<=etat->nb_sp; i++)
  67. {
  68. etat->Bio_tot = etat->Bio_tot + (etat->abondances[i] * etat->biomasse[i]);
  69. etat->Cout_tot = etat->Cout_tot + (etat->abondances[i] * etat->cout[i]);
  70. }
  71. etat->Bio_tot = (etat->Bio_tot)/1000;
  72. etat->Cout_tot = (etat->Cout_tot)/1000;
  73. /* MENU GENERAL */
  74. printf("-----------------------------------------------------------\n" );
  75. printf("\nBienvenue dans notre programme de simulations d'abondances.\n\n" );
  76. printf("-----------------------------------------------------------\n\n" );
  77. printf("Souhaitez-vous rediriger les résultats dans un fichier, 1 = oui ou 2 = Non\n" );
  78. scanf("%d", &choixf);
  79. if (choixf == 1)
  80. {
  81. printf("Entrez le nom du fichier à créer:\n" );
  82. scanf("%s", nom_fichier);
  83. f_resultat = fopen(nom_fichier, "w" );
  84. }
  85. do {
  86. printf("\n\n-----------------------------------------------------------\n" );
  87. printf("--------------------------MENU GENERAL---------------------\n" );
  88.         printf("-----------------------------------------------------------\n" );
  89. printf("1 - Afficher une description du milieu marin.\n" );
  90. printf("2 - Simuler l'évolution du milieu pour un certain nombre d'itérations.\n" );
  91. printf("3 - Statistiques pour 100 simulations.\n" );
  92. printf("4 - Quitter.\n" );
  93. scanf("%d",&choix1);
  94. printf("-----------------------------------------------------------\n\n" );
  95. switch (choix1)
  96. {
  97.  /* CHOIX = QUESTION 1 */
  98.  case 1 :
  99.  {
  100.   do {
  101.        /* DEFINITION DU MENU de la Question 1 */
  102.    printf("\n-----------------------------------------------------------\n" );
  103.    printf("            DESCRIPTION GENERALE DU MILIEU MARIN\n" );
  104.    printf("-----------------------------------------------------------\n" );
  105.    printf("1 - Afficher la description générale du milieu marin.\n" );
  106.    printf("2 - Afficher la description du milieu relative à une espèce en particulier.\n" );
  107.    printf("3 - Retour au menu.\n" );
  108.    scanf("%d",&choix2);
  109.    printf("-----------------------------------------------------------\n\n" );
  110.    switch (choix2)
  111.    {
  112.          /* Choix 1 = QUESTION 1.a */
  113.     case 1 :
  114.     {
  115.      printf("-----------------------------------------------------------\n" );
  116.      printf("            DESCRIPTION GENERALE DU MILIEU MARIN\n" );
  117.      printf("-----------------------------------------------------------\n\n" );
  118.         /* AFFICHAGE TABLEAU ABONDANCES */
  119.      printf("\nABONDANCES (en nombre d'individus) :\n" );
  120.      aff_tab_entier (etat->abondances, etat->tab_espece, etat->nb_sp);
  121.         /* AFFICHAGE TABLEAU SEUILS */
  122.      printf("\nSEUILS (en nombre d'individus) :\n" );
  123.      aff_tab_entier (etat->seuil, etat->tab_espece, etat->nb_sp);
  124.         /* AFFICHAGE TABLEAU SEUILS CRITIQUES */
  125.      printf("\nSEUILS-CRITIQUES (en nombre d'individus) :\n" );
  126.      aff_tab_entier (etat->seuil_critique, etat->tab_espece, etat->nb_sp);
  127.         /* AFFICHAGE MATRICE INTERACTIONS */
  128.      printf("\nINTERACTIONS :\n" );
  129.      aff_matrice(etat->interactions, etat->tab_espece, etat->nb_sp);
  130.         /* AFFICHAGE TABLEAU BIOMASSES UNITAIRES */
  131.      printf("\nBIOMASSE UNITAIRE (en g) :\n" );
  132.      aff_tab_reel (etat->biomasse, etat->tab_espece, etat->nb_sp);
  133.         /* AFFICHAGE BIOMASSE TOTALE */
  134.      printf("\nBIOMASSE TOTALE DU MILIEU (en kg) : %.2f\n",etat->Bio_tot);
  135.         /* AFFICHAGE TABLEAU COUTS UNITAIRES */
  136.                       printf("\nCOUTS UNITAIRES (en g) :\n" );
  137.      aff_tab_reel (etat->cout, etat->tab_espece, etat->nb_sp);
  138.         /* AFFICHAGE COUT TOTAL */
  139.      printf("\nCOUT TOTAL DU MILIEU (en kg) : %.2f\n",etat->Cout_tot);
  140.     };break;
  141.     /*Choix 1 = QUESTION 1.b*/
  142.     case 2 :
  143.     {
  144.      do {
  145.         /*Demande Choix d'une espèce*/
  146.       printf("-----------------------------------------------------------\n" );
  147.       printf("           IMPACT ENTRE LES ESPECES.\n" );
  148.       printf("-----------------------------------------------------------\n\n" );
  149.       printf("Veuillez choisir une espèce:\n" );
  150.       for (i=1;i<=etat->nb_sp;i++)
  151.       {
  152.        printf("%d : %s\n", i, etat->tab_espece[i].nom_espece);
  153.       }
  154.       scanf("%d", &choix1_b);
  155.       printf("\n-----------------------------------------------------------\n" );
  156.       if ((choix1_b<0) || (choix1_b>etat->nb_sp))
  157.       {
  158.        printf("Veuillez saisir un nombre entre 0 et %d.\n", etat->nb_sp);
  159.       }else{
  160.        printf("-----------------------------------------------------------\n" );
  161.     /* POUR CHAQUE ESPECE NOUS AFFICHONS LA LISTE DES ESPECES QUI ONT UN IMPACT SUR CELLE-CI */
  162.        printf("Le(s) %s ont un IMPACT SUR :\n",etat->tab_espece[choix1_b].nom_espece);
  163.        printf("POSITIVEMENT : " ); 
  164.        for (j=1; j<=etat->nb_sp; j++)
  165.        {
  166.         if (etat->interactions [choix1_b] [j]>0)
  167.         {
  168.          printf("%s (%.1f), ",  etat->tab_espece[j].nom_espece, etat->interactions [choix1_b] [j]);
  169.         }
  170.        }
  171.        printf("\nNEGATIVEMENT : " );
  172.        for (j=1; j<=etat->nb_sp; j++)
  173.        {
  174.         if (etat->interactions [choix1_b] [j]<0)
  175.         {
  176.          printf("%s (%.1f), ",  etat->tab_espece[j].nom_espece, etat->interactions [choix1_b] [j]);
  177.         }
  178.        }
  179.    /* PUIS NOUS AFFICHONS LA LISTE DES ESPECES IMPACTÉES PAR CELLE-CI */
  180.        printf("\n\nLe(s) %s sont IMPACTE(ES) PAR:\n",etat->tab_espece[choix1_b].nom_espece);
  181.        printf("POSITIVEMENT : " ); 
  182.        for (i=1; i<=etat->nb_sp; i++)
  183.        {
  184.         if (etat->interactions [i] [choix1_b]>0)
  185.         {
  186.          printf("%s (%.1f), ",  etat->tab_espece[i].nom_espece, etat->interactions [i] [choix1_b]);
  187.         }
  188.        }
  189.        printf("\nNEGATIVEMENT : " ); 
  190.        for (i=1; i<=etat->nb_sp; i++)
  191.        {
  192.         if (etat->interactions [i] [choix1_b]<0)
  193.         {
  194.          printf("%s (%.1f), ",  etat->tab_espece[i].nom_espece, etat->interactions [i] [choix1_b]);
  195.         }
  196.        }
  197.       }
  198.           } while ((choix1_b<1) || (choix1_b>=etat->nb_sp));
  199.      printf("\n" );
  200.     }; break;
  201.     case 3 : printf("\n\nRetour au menu.\n\n" );break;
  202.     default : printf ("\n\nVeuillez saisir une valeur entre 1 et 3.\n\n" );
  203.    }
  204.   }while (choix2!=3);
  205.  }break;
  206. /* QUESTION 2 : SIMULATION AVEC UN CERTAIN NOMBRE D'ITERATIONS */

Reply

Marsh Posté le 10-12-2015 à 14:23:49    

Bon, je te donne un élément de réponse:
Ça peut être fait pour les printf (quitte a faire un remplacement global printf -> printf_and_log) mais pas pour les scanf (y'a peut être moyen dans mais c'est nettement moins simple et j'ai pas le temps de me pencher dessus la).

 

Un petit fichier exemple pour que tu comprennes le principe:

Code :
  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. FILE *logfile;  // a déclarer en extern dans d'autres modules s'il y a lieu
  4. /* ne fera rien si logfile est à NULL */
  5. void logger(const char *fmt,...) {
  6.     if (logfile) {
  7.         va_list ap;
  8.         va_start(ap, fmt);
  9.         vfprintf(logfile, fmt, ap);
  10.         va_end(ap);
  11.     }
  12. }
  13. // sortie sur terminal et éventuellement log
  14. int printf_and_log(const char *fmt, ...) {
  15.     int n;
  16.     va_list ap, aq;
  17.     va_start(ap, fmt);
  18.     va_copy(aq, ap);
  19.     // en sortie terminal
  20.     n = vprintf(fmt, ap);
  21.     va_end(ap);
  22.     // en sortie log
  23.     if (logfile) {
  24.         vfprintf(logfile, fmt, aq);
  25.     }
  26.     va_end(aq);
  27.     return n;
  28. }
  29. int main() {
  30.     int answer = 42;
  31.     char *logfilename = "test.txt";
  32.     logfile = fopen(logfilename, "w" );
  33.     if (logfile == NULL) {
  34.         fprintf(stderr, "Can't open log file %s\n", logfilename);
  35.         return 1;
  36.     }
  37.     // n'ira pas dans le log
  38.     printf("Opened log file %s\n", logfilename);
  39.     // ira dans le log
  40.     printf_and_log("The answer is %d\n", answer);
  41.     printf_and_log("Who wrote this famous sentence?\n" );
  42.     printf_and_log("1. Isaac Asimov\n" );
  43.     printf_and_log("2. Arthur C Clarke\n" );
  44.     printf_and_log("3. Douglas Adams\n" );
  45.     printf_and_log("4. Jack Vance\n" );
  46.     printf_and_log("5. Obi-Wan Kenobi\n" );
  47.     int choice = 0;
  48.     scanf("%d", &choice);
  49.     // par moyen de faire autrement car on n'a pas de passage de passer automatiquement d'un &choice à un choice
  50.     // de manière simple
  51.     logger("%d\n", choice);
  52.     if (choice == 3) {
  53.         printf_and_log("Excellent!\n" );
  54.     } else {
  55.         printf_and_log("Too bad! Better luck next time.\n" );
  56.     }
  57.     fclose(logfile);
  58.     return 0;
  59. }
 

A+,

 


Message édité par gilou le 10-12-2015 à 14:24:30

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 10-12-2015 à 14:23:49   

Reply

Marsh Posté le 10-12-2015 à 23:21:42    

Bon, après avoir cogité un peu plus, je t'ai trouvé une solution qui marche sans modifier ton code.
 

Code :
  1. // fichier logging.h
  2. void log_open(char *logfilename);
  3. void log_close();
  4. #ifdef LOGGING
  5. int log_printf(const char *fmt, ...);
  6. int log_scanf(const char *fmt, ...);
  7. #define printf(...) log_printf(__VA_ARGS__)
  8. #define scanf(...) log_scanf(__VA_ARGS__)
  9. #endif


Code :
  1. // fichier logging.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5. #ifdef LOGGING
  6. // si on n'a pas getline en standard sur son systeme
  7. int getline (char **lineptr, size_t *n, FILE *stream);
  8. static FILE *logfile;
  9. void log_open(char *logfilename) {
  10.     logfile = fopen(logfilename, "w" );
  11.     if (logfile == NULL) {
  12.         fprintf(stderr, "Can't open log file %s\n", logfilename);
  13.         exit(EXIT_FAILURE);
  14.     }
  15. }
  16. void log_close() {
  17.     if (logfile) {
  18.         fclose(logfile);
  19.     }
  20.     logfile = NULL;
  21. }
  22. // sortie sur terminal et éventuellement log
  23. int log_printf(const char *fmt, ...) {
  24.     int n;
  25.     va_list ap, aq;
  26.     va_start(ap, fmt);
  27.     va_copy(aq, ap);
  28.     // en sortie terminal
  29.     n = vprintf(fmt, ap);
  30.     va_end(ap);
  31.     // en sortie log
  32.     if (logfile) {
  33.         vfprintf(logfile, fmt, aq);
  34.     }
  35.     va_end(aq);
  36.     return n;
  37. }
  38. // entrée sur terminal et éventuellement log
  39. int log_scanf(const char *fmt, ...) {
  40.     int n;
  41.     va_list ap;
  42.     char *line = NULL;
  43.     size_t size;
  44.     if ((getline(&line, &size, stdin)) == -1) {
  45.         fprintf(stderr, "ERROR while reading console input\n" );
  46.         exit(EXIT_FAILURE);
  47.     }
  48.     // en sortie log
  49.     if (logfile) {
  50.         fprintf(logfile, "%s", line);
  51.     }
  52.     va_start(ap, fmt);
  53.     // en sortie terminal
  54.     n = vsscanf(line, fmt, ap);
  55.     va_end(ap);
  56.     free(line);
  57.     return n;
  58. }
  59. #else
  60. void log_open(char *logfilename) {}
  61. void log_close() {}
  62. #endif


Comme j'ai pas de getline sur mon systeme, j'utilise celui (archi connu et utilisé) trouvé ici: http://www.opensource.apple.com/so [...] /getline.c
et le fichier exemple:

Code :
  1. //mylog.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5. #include "logging.h"
  6. int main() {
  7.     int answer = 42;
  8.     log_open("test.txt" );
  9.     printf("The answer is %d\n", answer);
  10.     printf("Who wrote this famous sentence?\n" );
  11.     printf("1. Isaac Asimov\n" );
  12.     printf("2. Arthur C Clarke\n" );
  13.     printf("3. Douglas Adams\n" );
  14.     printf("4. Jack Vance\n" );
  15.     printf("5. Obi-Wan Kenobi\n" );
  16.     int choice = 0;
  17.     scanf("%d", &choice);
  18.     if (choice == 3) {
  19.         printf("Excellent!\n" );
  20.     } else {
  21.         printf("Too bad! Better luck next time.\n" );
  22.     }
  23.     log_close();
  24.     return 0;
  25. }


 
Je compile ainsi:
gcc -DSTDC_HEADERS -DLOGGING -o mylog1.exe mylog.c logging.c getline.c
Le -DSTDC_HEADERS est un flag uniquement utile pour getline.c donc ne pas en tenir compte
(j'aurais pu aussi allouer un buffer de 256 ou 1024 caractères et utiliser gets plutôt que getline, en espérant que l'utilisateur n'ait jamais l'idée de taper une ligne plus longue que ça :D)
Ça me fait un exécutable qui écrit en console et dans un fichier de log.
Si je compile sans le flag -DLOGGING ça me fait un exécutable qui écrit en console seulement.
Les seules modifs à faire à son code sont:
- ajouter #include "logging.h" en tête de tous ses fichiers utilisant printf ou scanf
- faire un appel à log_open (et en fin à log_close) dans son programme principal.
C'est donc vraiment quelque chose de minimaliste.
 
Voilou!
 
REMARQUE: il y a une différence ici entre un scanf en mode LOGGING et un scanf normal:
Un scanf normal lira éventuellement plusieurs lignes, jusqu'à ce qu'il ait lu autant de données qu'il en attend (ou qu'il soit en mode échec)
Celui en mode LOGGING ne lira les données que sur une seule ligne.
Vu le fonctionnement interactif de ce programme, cela ne m'a pas paru être une restriction rédhibitoire ici.
 
A+,


Message édité par gilou le 10-12-2015 à 23:32:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed