cs_rt15
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
20 avril 2009 à 18:15
Tu devrais pouvoir t'inspirer du code suivant par exemple.
Il cherche tous les fichiers input_*.txt d'un répertoire et les concatènes dans un fichier output_%d.txt.
Où %d est le plus petit entier disponible ne correspondant pas à un fichier déjà existant.
Application console. Pour compiler sous gcc, ajouter -nostartfiles -nodefaultlibs -nostdlib -ffreestanding dans les options du lieur.
Pour compiler sous VC, s'arranger pour que le lieur ignore toutes les librairies par défaut (/nodefaultlib).
Sous VC, en cas d'erreur LNK2001 : __chkesp symbole externe non résolu -> Enlever /GZ des options de compilation
<hr size="2" width="100%" />#ifdef UNICODE
#define _UNICODE
#endif /* UNICODE */
#include <windows.h>
#include <tchar.h>
#define WORKING_DIR _T("C:\\Temp\\Test\")
HANDLE _hOutput; /* Fichier de sortie */
typedef BOOL (__stdcall *FILESYSTEM_ENUMFILEPROC)(const TCHAR*);
/**
* Alloue une zone mémoire en utilisant VirtualAlloc
*
* @param nSize Taille de la zone à allouer
* @return Pointeur sur la zone allouée
*/
void* __stdcall Mem_Alloc(const DWORD nSize)
{
return VirtualAlloc(NULL, nSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
}
/**
* Libère une zone mémoire allouée avec Mem_Alloc
*
* @param Pointeur sur la zone allouée
*/
void __stdcall Mem_Free(void *lpAddress)
{
VirtualFree(lpAddress, 0, MEM_RELEASE);
}
/**
* Affiche le texte indiqué dans la console
*
* @param lpText Texte à écrire dans la console
* @return FALSE en cas de problème
*/
BOOL __stdcall Con_WriteLn(const TCHAR *lpText)
{
DWORD nWritten; /* Réception du nombre de caractère écris */
char *lpOemText; /* Texte traduit en OEM */
DWORD nSize; /* Taille du texte à écrire */
BOOL bResult;
/* Traduction des caractère àùéè... */
nSize = lstrlen(lpText);
/* On aura un \n en plus */
nSize++;
lpOemText = (char*)Mem_Alloc(nSize);
CharToOem(lpText, lpOemText);
lstrcatA(lpOemText, "\n");
bResult = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), lpOemText,
nSize, &nWritten, NULL);
Mem_Free(lpOemText);
return bResult;
}
/**
* Affiche un message d'erreur correspondant à la dernière erreur Win32
*/
DWORD __stdcall Err_ShowLatest()
{
DWORD nLastError; /* Numéro de l'erreur */
LPTSTR lpMessageBuffer; /* Récupération du message */
nLastError = GetLastError();
/* Formatage du message */
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(void*)&lpMessageBuffer, 0, NULL);
/* Affichage du message */
MessageBox(NULL, lpMessageBuffer, _T("ERROR"), MB_OK | MB_ICONERROR);
LocalFree(lpMessageBuffer);
return nLastError;
}
/**
* Renvoie un handle sur un nouveau fichier
*
* @param lpDir Répertoire de création, terminé par un \
* @param lpName Nom du fichier, doit contenir un %d
*/
HANDLE __stdcall CreateNewFile(const TCHAR *lpDir, const TCHAR *lpName)
{
TCHAR lpFilePath[1024]; /* Chemin et nom du nouveau fichier */
HANDLE hResult;
int nI;
/* On boucle tant que le nom est utilisé */
nI = 0;
do
{
/* Nouveau nom potentiellement disponible */
lstrcpy(lpFilePath, lpDir);
lstrcat(lpFilePath, lpName);
wsprintf(lpFilePath, lpFilePath, nI);
/* On essaie de l'ouvrir comme nouveau fichier */
hResult = CreateFile(lpFilePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hResult != INVALID_HANDLE_VALUE) break;
nI++;
}
while (GetLastError() == ERROR_FILE_EXISTS);
return hResult;
}
/**
* Fonction qui va traiter les fichiers en entrée
*/
BOOL __stdcall HandleFile(const TCHAR* lpFile)
{
HANDLE hInput; /* Handle du fichier d'entrée */
char lpBuffer[2048]; /* Buffer de lecture */
DWORD nBytesRead; /* Récupération du nombre d'octets lus */
DWORD nBytesWritten; /* Récupération du nombre d'octets écrits */
Con_WriteLn(lpFile);
hInput = CreateFile(lpFile,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInput == INVALID_HANDLE_VALUE)
{
Err_ShowLatest();
goto the_end;
}
do
{
ReadFile(hInput, lpBuffer, sizeof(lpBuffer), &nBytesRead, NULL);
WriteFile(_hOutput, lpBuffer, nBytesRead, &nBytesWritten, NULL);
}
while (nBytesRead == sizeof(lpBuffer));
CloseHandle(hInput);
the_end:
return TRUE;
}
/**
* Enumère les fichier et répertoire d'un dossier
*
* La fonction appelée doit renvoyer TRUE pour que le listage continue.
*
* @param lpDir Répertoire, doit se terminer par \
* @param lpFileName Pattern de recherche
* @param lpCallBack Fonction appelée pour chaque fichier
*/
int __stdcall FileSys_EnumFiles(const TCHAR* lpDir, const TCHAR* lpFileName, FILESYSTEM_ENUMFILEPROC lpCallBack)
{
TCHAR lpFilePath[1024]; /* Chemin et nom d'un fichier en entrée */
WIN32_FIND_DATA findFileData; /* Information sur les fichiers trouvés */
HANDLE hFind; /* Handle sur la recherche */
int nResult;
nResult = 0;
lstrcpy(lpFilePath, lpDir);
lstrcat(lpFilePath, lpFileName);
/* Parcourt des fichiers d'entrée */
hFind = FindFirstFile(lpFilePath, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
if (GetLastError() != ERROR_FILE_NOT_FOUND)
goto the_end;
}
else
{
do
{
if (lstrcmp(findFileData.cFileName, _T(".")))
if (lstrcmp(findFileData.cFileName, _T("..")))
{
lstrcpy(lpFilePath, lpDir);
lstrcat(lpFilePath, findFileData.cFileName);
/* Appel de la callback pour tous les fichiers */
if (! lpCallBack(lpFilePath))
{
nResult = 1;
goto the_end;
}
}
}
while (FindNextFile(hFind, &findFileData));
FindClose(hFind);
/* Vérification que l'on est sorti de le la boucle */
/* car il n'y a plus de fichiers. */
if (GetLastError() != ERROR_NO_MORE_FILES)
goto the_end;
}
nResult = 1;
the_end:
return nResult;
}
/**
* Main
*/
int __cdecl mainCRTStartup()
{
int nResult;
nResult = 0;
/* Création d'un nouveau fichier de sortie */
_hOutput = CreateNewFile(WORKING_DIR, _T("output_%d.txt"));
if (_hOutput == INVALID_HANDLE_VALUE)
{
nResult = Err_ShowLatest();
goto the_end;
}
/* Traitement des fichiers en entrée */
if (! FileSys_EnumFiles(WORKING_DIR, _T("input_*.txt"), HandleFile)) Err_ShowLatest();
CloseHandle(_hOutput);
the_end:
/* ExitProcess nécessaire car sinon c'est un ExitThread */
ExitProcess(nResult);
/* Pour esquiver le warning */
return 0;
}