[C] Boucle avec strcat pour créer plusieurs fichiers

Boucle avec strcat pour créer plusieurs fichiers [C] - C - Programmation

Marsh Posté le 10-07-2006 à 10:50:59    

Bonjour,
    Je galère actuellement sur un petit programme que je fais en C, qui a pour but (globalement) de découper un fichier .txt en plusieurs petits fichiers.
 
Les petits fichiers en question doivent s'appeler "fichier1", "fichier2", "fichier3" etc... J'ai donc tenté de faire une boucle contenant :
 
   

Code :
  1. int i=1;
  2.    char* A;
  3.    strcpy(Filename,"C:\\Test\\Fichier" );
  4.    strcat(Filename,(itoa(i,A,10)));
  5.    strcat(Filename,".txt" );
  6.    printf("%c\n",Filename);
  7.    FILE* file2 = fopen(Filename,"w" );


 
Apparemment c'est la ligne où je fais l'itoa qui déconne (enfin ça compile mais le programme plante). D'après les prototypes, itoa renvoit un char*, mais strcat attend un const char *. Mon problème peut-il venir de là ? Comment le résoudre alors ?  :??:  
 
Merci d'avance pour votre aide précieuse  :jap: .


Message édité par Zboss le 10-07-2006 à 10:51:36
Reply

Marsh Posté le 10-07-2006 à 10:50:59   

Reply

Marsh Posté le 10-07-2006 à 11:04:06    

Tu peux utiliser sprintf(), c'est plus imple:

Code :
  1. int i;
  2. for(i = 0; i < N; i++) {
  3. sprintf(filename, "C:\\Test\\Fichier%d", i);
  4. printf("Ouverture de \"%s\"", filename);
  5. FILE *file = fopen(Filename,"w" );
  6. ...
  7. }


Message édité par simple_stupid le 10-07-2006 à 11:05:07
Reply

Marsh Posté le 10-07-2006 à 11:14:55    

En fait au lieu de créer un char* A, il fallait créer un char A[10]; (par exemple), et ça marche... Quand je pense au temps que j'ai perdu pour ça...
 
Mais merci pour ton exemple avec sprintf(), je ne connaissais pas du tout  :jap: .
 

Reply

Marsh Posté le 10-07-2006 à 11:15:41    

Pour répondre réelement à ton problème, tu utilise le pointeur char* A dans itoa. Hors c'est dans ce pointeur que tu veux placer la valeure de i, mais tu n'a pas aloué de mémoire pour ton pointeur. un char A[2]; aurait fonctionné mais il faudrait à chaques fois reset A.
 
Utilise plutot une méthode plus simple telle que celle-ci:
 

Code :
  1. char Filename[256];
  2. FILE *fp = NULL;
  3. for(int i = 0; i < nbr_fichiers; i++)
  4. {
  5. sprintf( Filename, "C:\\Test\\Fichier%i.txt", i );
  6. printf( "Ouverture de \"%s\"", Filename );
  7. fp = fopen( Filename, "w" );
  8. memset( Filename, 0x00, 256 ); // On reset le nom de fichier pour pas se trouver avec 10 nom de fichiers à la suite.
  9. // Ecriture dans ton fichier...
  10. fclose( fp ); // n'oublions pas de fermer.
  11. }

Reply

Marsh Posté le 10-07-2006 à 11:18:37    

AiM a écrit :

Pour répondre réelement à ton problème, tu utilise le pointeur char* A dans itoa. Hors c'est dans ce pointeur que tu veux placer la valeure de i, mais tu n'a pas aloué de mémoire pour ton pointeur. un char A[2]; aurait fonctionné mais il faudrait à chaques fois reset A.
 
Utilise plutot une méthode plus simple telle que celle-ci:
 

Code :
  1. char Filename[256];
  2. FILE *fp = NULL;
  3. for(int i = 0; i < nbr_fichiers; i++)
  4. {
  5. sprintf( Filename, "C:\\Test\\Fichier%i.txt", i );
  6. printf( "Ouverture de \"%s\"", Filename );
  7. fp = fopen( Filename, "w" );
  8. memset( Filename, 0x00, 256 ); // On reset le nom de fichier pour pas se trouver avec 10 nom de fichiers à la suite.
  9. // Ecriture dans ton fichier...
  10. fclose( fp ); // n'oublions pas de fermer.
  11. }



 
Merci pour les explications précises  :jap: .

Reply

Marsh Posté le 10-07-2006 à 11:24:06    

AiM a écrit :

Pour répondre réelement à ton problème, tu utilise le pointeur char* A dans itoa. Hors c'est dans ce pointeur que tu veux placer la valeure de i, mais tu n'a pas aloué de mémoire pour ton pointeur. un char A[2]; aurait fonctionné mais il faudrait à chaques fois reset A.


 
Oui, et itoa n'est pas ANSI, elle n'est absolument pas standard.
Sinon pour le code, tu n'as pas besion (dans ce cas) de mettre le nom à 0. Tu utilises sprintf, pas strcat, et étant donné que les noms sont de longueur croissante, il n'y aura pas de problème de recouvrement/concaténation.
 
On peut aussi noter que si le chemin est long, on perd un peu en performance à recopier à chaque fois le préfixe: on pourrait, dans ce cas, se contenter de copier l'indice à la fin du préfixe via strcpy, ou memcpy, après avoir préalablement converti l'indice en chaîne de caractère.
Mais sprintf() est plus simple, plus propre, plus sûre, et bien plus flexible...

Reply

Marsh Posté le 10-07-2006 à 11:25:11    

AiM a écrit :

Code :
  1. char Filename[256];



 
Plutôt que 256, c'est plus simple d'utiliser la constante standard FILENAME_MAX, qui a l'avantage d'être définie en fonction du système sur lequel tu compiles ton binaire. ;)
 
De plus, si le compilateur est C99, tu peux utiliser snprintf() plutôt que sprintf(), qui a le grand avantage de s'assurer que tu n'auras pas de dépassement de capacité.
 
Enfin, lorsque tu utilises fopen(), il faut s'assurer que le descripteur renvoyé n'est pas NULL pour vérifier que la création du fichier s'est bien déroulée. Dans le cas contraire, tu auras de magnifiques plantages.

Reply

Marsh Posté le 10-07-2006 à 11:34:38    

Mais j'ai juste écrit l'ouverture après je vais pas lui écrire tout son code... Et pour le 256 oui ok pourquoi pas c'est sur mais on s'en tape un peux sous windows c'est 260..
Pour snprintf tu peux l'écrire toi même en deux secondes.

Reply

Marsh Posté le 10-07-2006 à 11:37:54    

AiM a écrit :

Mais j'ai juste écrit l'ouverture après je vais pas lui écrire tout son code... Et pour le 256 oui ok pourquoi pas c'est sur mais on s'en tape un peux sous windows c'est 260..
Pour snprintf tu peux l'écrire toi même en deux secondes.


 
Tout à fait d'accord pour le snprintf().
Il ne faut pas utiliser du C non standard (ANSI) quand on peut coder soi-même (ou récupérer) des implémentations en C ANSI: la portabilité c'est important!

Reply

Marsh Posté le 10-07-2006 à 11:39:33    

Euh, C99 c'est la norme, c'est donc standard, et depuis le temps les compilateurs l'implémentent, hein [:petrus75]

Reply

Marsh Posté le 10-07-2006 à 11:39:33   

Reply

Marsh Posté le 10-07-2006 à 11:41:21    

Sous MSVC 2003, snprintf n'existe pas dans la lib standard. mais il existe sous _snprintf ce n'est donc pas une fonction ANSI .. Mais on peut largement l'utiliser  :sol:

Reply

Marsh Posté le 10-07-2006 à 11:44:50    

La norme, ca a toujours été l'ANSI, et ça le restera. Le C99 n'est pas entièrement supporté par les compilos.
Après, si tu considères que les VLA sont une bonne chose, bon, bah.

Reply

Marsh Posté le 10-07-2006 à 11:48:11    

JE ne dis pas le contraire. Mais c'est quoi une VLA au juste ? (Version Largement Améliorée ? ok je sort )

Reply

Marsh Posté le 10-07-2006 à 11:52:42    

Je me suis déjà servi une ou deux fois des VLA.  
Quand c'est bien utilisé ça peut allèger le code, mais c'est vrai qu'on peut tout à fait s'en passer.
 
Pour la norme, ISO C c'est C90 finalement. Je ne vois pas de problème à dire qu'un développement se base sur C99, c'est tout à fait standard, même si ça peut forcer à mettre un compilateur à jour sur une cible (ce qui, dans le travail que je réalise, ne constitue aucunement une difficulté, mais je conçois que ça peut l'être dans d'autres domaines).
 

AiM a écrit :

JE ne dis pas le contraire. Mais c'est quoi une VLA au juste ? (Version Largement Améliorée ? ok je sort )


 
Variable-Length Array.
C'est-à-dire qu'on peut définir un tableau avec des variables (évidemment une fois le tableau défini, des modifications sur la variable n'entrainent pas de modification sur la taille du tableau).
 
Exemple :


void foo(int bar)
{
   char *foobar[bar + 1];
 
   blahcode
}


(je tiens à préciser parce que sinon je vais y avoir droit, que cet exemple ne reflète pas une utilisation idéale du VLA :o )

Message cité 2 fois
Message édité par Elmoricq le 10-07-2006 à 11:59:52
Reply

Marsh Posté le 10-07-2006 à 12:03:37    

Elmoricq a écrit :


Pour la norme, ISO C c'est C90 finalement. Je ne vois pas de problème à dire qu'un développement se base sur C99, c'est tout à fait standard, même si ça peut forcer à mettre un compilateur à jour sur une cible (ce qui, dans le travail que je réalise, ne constitue aucunement une difficulté, mais je conçois que ça peut l'être dans d'autres domaines).


 
On est d'accord. Je dis juste qu'il vaut mieux utiliser des librairies ansi déjà codées en ANSI plutôt que d'utiliser des fonctions non-ansi.
 

Citation :


(je tiens à préciser parce que sinon je vais y avoir droit, que cet exemple ne reflète pas une utilisation idéale du VLA :o )


 
Mais non, mais non  ;)  

Reply

Marsh Posté le 10-07-2006 à 14:44:49    

Elmoricq a écrit :

Je me suis déjà servi une ou deux fois des VLA.


[:vomi]Si il n'y pas de place on est pas prévenu...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 10-07-2006 à 14:47:29    

Emmanuel Delahaye a écrit :

[:vomi]Si il n'y pas de place on est pas prévenu...


 
Ah tiens, oui.  [:uxam]  
 
Et de fait, là comme ça, je ne vois pas comment on peut le tester.
Hmm. Je crois qu'en une seule phrase tu viens de démonter tout intérêt pour cette fonctionnalité (mais je suis vexé de ne pas y avoir pensé :/ )

Reply

Marsh Posté le 11-07-2006 à 23:25:24    

Je profite de ce topic que j'ai créé pour poser une petite question dans la continuité de mon programme : je crée donc 6 fichiers .txt qui sont dans le dossier C:\Test\ . Je voudrais qu'à la fin de l'exécution de mon programme, le dossier C:\Test\ s'affiche à l'écran, c'est possible ?


---------------
Mario Kart for Ever
Reply

Marsh Posté le 12-07-2006 à 07:38:12    

Zboss a écrit :

Je profite de ce topic que j'ai créé pour poser une petite question dans la continuité de mon programme : je crée donc 6 fichiers .txt qui sont dans le dossier C:\Test\ . Je voudrais qu'à la fin de l'exécution de mon programme, le dossier C:\Test\ s'affiche à l'écran, c'est possible ?


opendir() / readdir(). C'est pas du C standard, mais c'est POSIX.1 donc très portable. Il y a des détails dans la FAQ...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

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