JeanMarcP
Messages postés7Date d'inscriptionmardi 22 avril 2008StatutMembreDernière intervention22 avril 2008
-
22 avril 2008 à 10:56
cs_jfrancois
Messages postés482Date d'inscriptionvendredi 26 août 2005StatutMembreDernière intervention 5 décembre 2009
-
22 avril 2008 à 18:19
Bonjour
J'ai besoin, sur un vieux PC sous DOS, de modifier un fichier texte de la façon suivante :
Entre les 23ème et 24ème virgule, je dois ajouter le mot TEST, puis copier le fichier dans un répertoire K:\TEST
1-De quoi ai-je besoin pour que le programme tourne sous DOS ?
2-Comment faire ?
Je n'ai jamais fait de C, mais je connais VB par exemple
cs_jfrancois
Messages postés482Date d'inscriptionvendredi 26 août 2005StatutMembreDernière intervention 5 décembre 20092 22 avril 2008 à 17:10
Voilà ! il suffit d'externaliser le traitement d'un fichier dans une fonction (TraiterFichier() ici) et d'appeler cette fonction dans une boucle de parcours des fichiers qui répondent aux critères :
// --- Constantes
static const int iPositionInsertion = 24; // devant cette virgule
static const char* szInsertion = "TEST";
static const int iLongueurInsertion = strlen(szInsertion);
static const char* szRepertoire = "K:\\TEST\";
// ------------------
// TRAITER UN FICHIER
// ------------------
bool TraiterFichier
(
const char* pszNomFichierEntree // E:nom du fichier à traiter
) // S:état du traitement
{
// --- Buffer de lecture du fichier
static const int iTailleBuffer = 64 * 1024; // taille maxi
char acBuffer[iTailleBuffer];
// --- Présentation du fichier à traiter
printf("\nTraitement du fichier "%s"\n",pszNomFichierEntree);
// --- Ouvrir/lire/fermer le fichier en entrée
printf("- Lecture du fichier");
FILE* fp = fopen(pszNomFichierEntree,"rt");
if (fp == NULL)
{
printf(" *** ERREUR ***\n");
return false;
}
int iTailleFichier = fread(acBuffer,1,iTailleBuffer,fp);
fclose(fp);
printf(", %d caracteres lus\n",iTailleFichier);
// --- Traiter le buffer
int iCompteurVirgule = 0;
for (int i=0 ; i
// --- 1) Décaler de "iLongueurInsertion" caractères
for (int j=iTailleFichier ; j>=i ; --j)
acBuffer[j + iLongueurInsertion] = acBuffer[j];
// --- 2) Insérer le texte
strncpy(&acBuffer[i],szInsertion,iLongueurInsertion);
// --- 3) Traitement du buffer terminé
iTailleFichier += iLongueurInsertion;
break;
}
}
}
if (iCompteurVirgule < iPositionInsertion)
{
printf("- *** FICHIER NON MODIFIE ***\n");
return true;
}
// --- Nom complet du fichier en sortie
char szNomFichierSortie[_MAX_PATH];
strcpy(szNomFichierSortie,szRepertoire);
strcat(szNomFichierSortie,pszNomFichierEntree);
// --- Ouvrir/écrire/fermer le fichier en sortie
printf("- Ecriture du fichier "%s"",szNomFichierSortie);
fp = fopen(szNomFichierSortie,"wt");
if (fp == NULL)
{
printf(" *** ERREUR ***\n");
return false;
}
fwrite(acBuffer,iTailleFichier,1,fp);
fclose(fp);
printf(", %d caracteres ecris\n",iTailleFichier);
return true;
}
// -------------------
// FONCTION PRINCIPALE
// -------------------
int main(int argc,char** argv)
{
// --- Nom du/des fichiers à traiter
char szNomFichier[_MAX_PATH];
// --- Présentation
printf("\nMODIFICATION DE FICHIER(S)\n");
if (argc == 1)
{
// --- Fichiers d'extension TXT par défaut
strcpy(szNomFichier,"*.TXT");
}
if (argc == 2)
{
// --- Fichier(s) dans le paramètre 1
strcpy(szNomFichier,argv[1]);
}
else if (argc > 2)
{
printf("Utilisation : test nom_fichier(s)\n");
printf("Traiter le(s) fichier(s) "nom_fichier(s)" dans le repertoire courant\n");
printf("Fichier(s) modifie(s) cree(s) dans le repertoire "%s"\n",szRepertoire);
printf("Exemples de traitement :\n");
printf(" test --> tous les fichiers d'extension "txt"\n");
printf(" test *.dat --> tous les fichiers d'extension "dat"\n");
printf(" test fic.* --> tous les fichiers de nom "fic" quelque soit l'extension\n");
printf(" test fic.log --> le fichier "fic.log"\n");
return 0;
}
printf("Traitement de "%s"\n",szNomFichier);
// --- Positionner sur le premier fichier du répertoire courant
// --- et boucler tant qu'on trouve des fichiers
WIN32_FIND_DATA Find;
HANDLE hFichier = FindFirstFile(szNomFichier,&Find);
do
TraiterFichier(Find.cFileName);
while (FindNextFile(hFichier,&Find));
return 0;
}
Ce qui donne :
test
MODIFICATION DE FICHIER(S)
Traitement de "*.TXT"
Traitement du fichier "Test_modif_1.txt"
- Lecture du fichier, 106 caracteres lus
- Insertion de "TEST" devant la virgule 24
- Ecriture du fichier "Z:\Traces\Test_modif_1.txt", 110 caracteres ecri
Traitement du fichier "Test_modif_2.txt"
- Lecture du fichier, 71 caracteres lus
- Insertion de "TEST" devant la virgule 24
- Ecriture du fichier "Z:\Traces\Test_modif_2.txt", 75 caracteres ecris
Traitement du fichier "Test_modif_3.txt"
- Lecture du fichier, 83 caracteres lus
- Insertion de "TEST" devant la virgule 24
- Ecriture du fichier "Z:\Traces\Test_modif_3.txt", 87 caracteres ecris
Traitement du fichier "Test_modif_4.txt"
- Lecture du fichier, 71 caracteres lus
- Insertion de "TEST" devant la virgule 24
- Ecriture du fichier "Z:\Traces\Test_modif_4.txt", 75 caracteres ecris
cs_jfrancois
Messages postés482Date d'inscriptionvendredi 26 août 2005StatutMembreDernière intervention 5 décembre 20092 22 avril 2008 à 12:37
Bonjour,
Voici un essai commenté en C/C++ (sous Visual C++ 6.0) qui peut être utilisé directement ou servir de base. Le fichier à modifier est passé en paramètre et doit se trouver dans le répertoire courant et ne pas faire plus de 64Koctets (modifiable dans le programme). Le fichier modifié est créé dans le répertoire K:\TEST avec le même nom :
#include <stdio.h>
int main(int argc,char** argv)
{
// --- Constantes
static const int iPositionInsertion = 24; // devant cette virgule
static const char* szInsertion = "TEST";
static const int iLongueurInsertion = strlen(szInsertion);
static const char* szRepertoire = "K:\\TEST\";
// --- Buffer de lecture du fichier
static const int iTailleBuffer = 64 * 1024; // taille maxi
char acBuffer[iTailleBuffer];
// --- Présentation et contrôle du paramètre
printf("\nMODIFICATION D'UN FICHIER\n");
if (argc != 2)
{
printf("Utilisation: test nom_du_fichier\n");
printf("Le fichier a modifier "nom_du_fichier" doit etre dans le repertoire courant\n");
printf("Le fichier modifie "nom_du_fichier" est cree dans le repertoire "%s"\n",szRepertoire);
return 0;
}
// --- Ouvrir/lire/fermer le fichier en entrée
printf("Lecture du fichier %s\n",argv[1]);
FILE* fp = fopen(argv[1],"rt");
if (fp == NULL)
{
printf("*** Erreur a l'ouverture du fichier ***\n");
return 0;
}
int iTailleFichier = fread(acBuffer,1,iTailleBuffer,fp);
fclose(fp);
printf("- %d caracteres lus dans %s\n",iTailleFichier,argv[1]);
// --- Traiter le buffer
int iCompteurVirgule = 0;
for (int i=0 ; i
// --- 1) Décaler de "iLongueurInsertion" caractères
for (int j=iTailleFichier ; j>=i ; --j)
acBuffer[j + iLongueurInsertion] = acBuffer[j];
// --- 2) Insérer le texte
strncpy(&acBuffer[i],szInsertion,iLongueurInsertion);
// --- 3) Traitement du buffer terminé
iTailleFichier += iLongueurInsertion;
break;
}
}
}
if (iCompteurVirgule < iPositionInsertion)
{
printf("*** Fichier non modifie ***\n");
return 0;
}
// --- Nom complet du fichier en sortie
char szNomFichier[MAX_PATH];
strcpy(szNomFichier,szRepertoire);
strcat(szNomFichier,argv[1]);
// --- Ouvrir/écrire/fermer le fichier en sortie
printf("Ecriture du fichier %s\n",szNomFichier);
fp = fopen(szNomFichier,"wt");
if (fp == NULL)
{
printf("*** Erreur a l'ouverture du fichier ***\n");
return 0;
}
fwrite(acBuffer,iTailleFichier,1,fp);
fclose(fp);
printf("- %d caracteres ecris dans %s\n",iTailleFichier,szNomFichier);
return 0;
}
Ce qui donne :
C:\Temp\test test.txt
MODIFICATION D'UN FICHIER
Lecture du fichier test.txt
- 83 caracteres lus dans test.txt
Insertion de "TEST" devant la virgule 24
Ecriture du fichier K:\TEST\test.txt
- 87 caracteres ecris dans K:\TEST\test.txt
JeanMarcP
Messages postés7Date d'inscriptionmardi 22 avril 2008StatutMembreDernière intervention22 avril 2008 22 avril 2008 à 13:26
Merci beaucoup Jean-François
Par contre je ne possède par VC 6... j'ai essayé de compiler avec BloodShield C++ (compilateur gratuit) mais j'ai plein d'erreur (notamment sur tout ce qui commence par str...), je suis en train de télécharger c++ 2008 express, mais cela sera-t-il compatible ?
De plus l'EXE généré passera-t-il sous DOS ?
cs_jfrancois
Messages postés482Date d'inscriptionvendredi 26 août 2005StatutMembreDernière intervention 5 décembre 20092 22 avril 2008 à 13:44
Il n'y a aucune raison que ça ne passe pas sous C++ express 2008, c'est du code très basique qui tourne sans problème sous DOS bien sûr. Il manque les 2 includes string.h et stdlib.h et il faut changer MAX_PATH en _MAX_PATH ! (le source dans lequel j'ai saisi cet exemple à d'autres includes que j'avais oublié de passer en commentaire)
JeanMarcP
Messages postés7Date d'inscriptionmardi 22 avril 2008StatutMembreDernière intervention22 avril 2008 22 avril 2008 à 16:16
J'ai peur d'abuser...mais je me lance !
Si je veux que cela fonctionne en lançant TEST.EXE *.TXT au lieu de donner le nom du fichier en paramètre c'est possible ? ou bien directement le fait de lancer TEST.EXE traite tous les fichiers en extension TXT ?
Merci d'avance aux âmes charitables qui ouvrent sur ce forum...
JeanMarcP
Messages postés7Date d'inscriptionmardi 22 avril 2008StatutMembreDernière intervention22 avril 2008 22 avril 2008 à 16:59
Je viens d'aller à la pêche aux infos sur la fonction FindFirstFile et j'ai trouvé le code suivant. L'ennui c'est que mes connaissances en C sont trop limite pour savoir où brancher cette fonction...
HANDLE hFind;
WIN32_FIND_DATA FindData;
// Début de la recherche
hFind=FindFirstFile ("*.TXT", &FindData);
if (hFind!=INVALID_HANDLE_VALUE)
{
// Si le fichier trouvé n'est pas un dossier mais bien un fichier
if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
*** Faire le traitement ***
}
// Fichiers suivants
while (FindNextFile (hFind, &FindData))
{
if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
*** là j'ai pas compris à quoi cela correspond ****
}
}
}
// Fin de la recherche
FindClose (hFind);
cs_jfrancois
Messages postés482Date d'inscriptionvendredi 26 août 2005StatutMembreDernière intervention 5 décembre 20092 22 avril 2008 à 17:25
Ce code est "brut de décoffrage" bien sûr. Il manque quelques test de sécurité !
Par exemple, pour éliminer les répertoires qui pourraient être pris en compte :
WIN32_FIND_DATA Find;
HANDLE hFichier = FindFirstFile(szNomFichier,&Find);
do
{
if ((Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
TraiterFichier(Find.cFileName);
} while (FindNextFile(hFichier,&Find));