Lecture d'un fichier txt [Résolu]

Signaler
Messages postés
11
Date d'inscription
samedi 22 septembre 2007
Statut
Membre
Dernière intervention
30 avril 2008
-
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
-
Chers amis de la troisième lettre de l'alphabet bonjour,

J'ai écrit une petite fonction, copy_rep, permettant de copier un répertoire temp vers un autre répertoire. Copy_rep (toto), mettant les fichiers dan le répertoire toto marche très bien avec des ligne ressemblant à celle-ci :
char rep_base[55]="D:\\Medias\";
strcat (rep_base, mot2);
char creer_repb[70]="md ";
strcat (creer_repb,rep_base);
Bref, la chose marche pour le mieux, ce que je désire pouvoir faire pour communiquer avec un logiciel qui s'appelle R, c'est de pouvoir lire le nom du répertoire dans un fichier txt. J'ai alors écrits ce bout de programme pour lancer ma fonction :

FILE *stream;
char *fich;

stream = fopen("D:\\Medias\\temp\\mot.txt", "r");
fscanf(stream,"%c",fich);
fclose(stream);

Malheureusement, ce que la fonction lit dans le fichier n'a pas l'aire de marcher avec ce qu'elle lit? Et je ne suis point apte à comprendre pourquoi?
Merci d'avance Christophe

P.S. J'ai déjà écrit ce message et je m?excuse s'il y a eu un problème avec.,.

14 réponses

Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Version optimisé:

typedef struct _openl
{
HANDLE hFile;
BYTE* Buffer;
DWORD FileSize;
}OPENL, *LPOPENL;

LPOPENL __stdcall OpenLine(char* FileName)
{
LPOPENL lpoLine;
DWORD br;
lpoLine = (LPOPENL) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, sizeof(OPENL));
lpoLine->hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
if(lpoLine->hFile == INVALID_HANDLE_VALUE) return;
lpoLine->FileSize = GetFileSize(lpoLine->hFile, 0);
lpoLine->Buffer = (BYTE*) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, lpoLine->FileSize+1);
ReadFile(lpoLine->hFile, lpoLine->Buffer, lpoLine->FileSize, &br, 0);
return (LPOPENL) lpoLine;
}

DWORD __stdcall ReadLine(LPOPENL lpoLine, DWORD nLine, char* LineOut)
{
DWORD LineSize 0, pBuff 0, ln = 0, br;
while(1)
{
if(lpoLine->Buffer[pBuff] == 0x0A)
{
ln++;
if(ln == nLine) break;
LineSize = 0;
}
if(pBuff == lpoLine->FileSize) break;
pBuff++; LineSize++;
}
if(lpoLine->Buffer[pBuff] == 0x0A) lpoLine->Buffer[pBuff-1] = 0x00;
LineSize--;
pBuff -= LineSize;
memcpy(LineOut, &lpoLine->Buffer[pBuff], LineSize);
return LineSize;
}

void __stdcall CloseLine(LPOPENL lpoLine)
{
CloseHandle(lpoLine->hFile);
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpoLine->Buffer);
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpoLine);
}

LPOPENL lpoLine;
char Line[MAX_PATH+4];
lpoLine = OpenLine("C:\\ton_fichier.xxx);
ReadLine(lpoLine, Le_numero_de_la_ligne, Line);
//...
CloseLine(lpoLine);

Voila..

Neo_Fr
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
int main(void)
{
char Ligne[MAX_PATH+4];
LPOPENL lpoLine;
lpoLine = OpenLine("C:\\test.txt"); // On ouvre le fichier et on le charge...
ReadLine(lpoLine, 1, Ligne); // On charge la ligne 1
printf("%s\n", Ligne); // On l'affiche
ReadLine(lpoLine, 2, Ligne); // On charge la ligne 2
printf("%s\n", Ligne); // On l'affiche
// etc..
CloseLine(lpoLine); // On referme et on libere..

system("PAUSE");
return 0;
}

Plus simple que ca c'est pas possible =)

Neo_Fr
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
J'espère que tu alloues de la mémoire à fich avant de l'utiliser...sinon quand tu fais fscanf tu lui indiques %c ce qui signifie un seul caractère il me semble, faudrait plutôt utiliser %s.
Messages postés
11
Date d'inscription
samedi 22 septembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

Oui merci, j'avoue que j'ai essayé plein de chose et j'avais essayé le %s mais le bug ne viens pas de là, dslé...
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
fscanf s'arrête au premier espace rencontré je crois.
Essais d'utiliser fread. Pour connaitre la taille du fichier, utilise fseek et ftell.

C++ (@++)<!--
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Salut,
Si tu veux lire une ligne ds un fichier:

DWORD __stdcall ReadLine(DWORD nLine, char* FileName, char* LineOut)
{
HANDLE hFile;
BYTE* Buffer;
DWORD FileSize, LineSize 0, pBuff 0, ln = 0, br;
hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
if(hFile == INVALID_HANDLE_VALUE) return 0;
FileSize = GetFileSize(hFile, 0);
Buffer = (BYTE*) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, FileSize+1);
ReadFile(hFile, Buffer, FileSize, &br, 0);
if(br != FileSize) goto End;
while(1)
{
if(Buffer[pBuff] == 0x0A)
{
ln++;
if(ln == nLine) break;
LineSize = 0;
}
if(pBuff == FileSize) break;
pBuff++; LineSize++;
}
if(Buffer[pBuff] == 0x0A) Buffer[pBuff-1] = 0x00;
LineSize--;
pBuff -= LineSize;
memcpy(LineOut, &Buffer[pBuff], LineSize);
End:
CloseHandle(hFile);
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, Buffer);
return LineSize;
}

Dans ton cas tu fais:
char Line[MAX_PATH+4];
ReadLine(Le_Numero_de_la_ligne, "C:\\tonfichier.xxx", Line);

Neo_Fr
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
Ben non.

On ne peut pas réouvrir, réallouer la mémoire, relire le fichier et renaviguer à partir du début du buffer à chaque fois que l'on veut extraire une ligne. Ça prendra un temps fou.
Effectuer ces traitements sur un buffer contenant déjà tout le fichier serait plus judicieux je crois.

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
Ouffff.... c'est compliqué ton truc.
Voici la version la plus simple que j'ai pu faire.

char *GetLine (char *lpDest, char *lpBuffer, UINT *piSize, UINT iLine)
{
    char *pDest, *pFinalPos, *pBeg;

//    if(!buffer || !piSize || !buffer_size) return 0;

    pFinalPos = lpBuffer+*piSize;
    pDest = lpDest;

    while(iLine > 0) {
       while(*lpBuffer != '\r' && *lpBuffer != '\n')
            if(++lpBuffer >= pFinalPos) return 0;

       lpBuffer++; if(*lpBuffer == '\n') lpBuffer++;
       iLine--;
    }

    pBeg = lpBuffer;

    while(*lpBuffer != '\r' && *lpBuffer != '\n') {
        if(lpBuffer >= pFinalPos) break;
        *pDest++ = *lpBuffer++;
    }

    *piSize = lpBuffer-pBeg;
    *pDest = 0;

    return pBeg;
}

int main (int argc, char *argv[])
{
    char *lpBuffer, lpLine[50];
    HANDLE hFile;
    DWORD dwSize;

    hFile = CreateFile("d:\\test.txt", GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);

    if(hFile != INVALID_HANDLE_VALUE) {
        dwSize = GetFileSize(hFile, 0);
        lpBuffer = VirtualAlloc(0, dwSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);

        if(lpBuffer) {
            if(ReadFile(hFile, lpBuffer, dwSize, &dwSize, 0)) {
                // On commence à compter à partir de 0
                // On extrait donc la seconde ligne
                if(GetLine(lpLine, lpBuffer, &dwSize, 1))
                    printf("%s\nTaille: %d\n", lpLine, dwSize);
            }

            VirtualFree(lpBuffer, 0, MEM_RELEASE);
        }

        CloseHandle(hFile);
    }
       

    return 0;
}

Le paramètre piSize est bidirectionnel.
Il prend en entré la taille de lpBuffer et contient en sortie la taille de lpDest (moins le 0 de fin de chaine).
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
En passent, cette version de GetLine est fait pour lire des fichiers au format windows c'est à dire avec des saut de ligne au format \r\n.

Petite correction:
lpBuffer++; if(*lpBuffer == '\n') lpBuffer++;
est inutile.
À remplacer par
lpBuffer += 2;

Aussi dans les 2
while(*lpBuffer != '\r' && *lpBuffer != '\n')
Pas nécessaire de tester si le caractère egal '\n'

C++ (@++)<!--
Messages postés
11
Date d'inscription
samedi 22 septembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

je dois vous avouer que le temp, je m'en fous un peu, si je peux me permettre de parler avec la moindre des trivialité, car le truc dois de toute façon tourner sur une application qui fait de la statistique textuelle qui prend des plombe donc, en dessous de 1 minute, ça change que dalle pour moi.

Tout le seul problème et que le fread à l'aire de faire le même effet que lefsacan quant au ReadLine, il me renvoie "H#%" alors que "toto" était dans mon fichier txt. Je sais pas peut-être est-ce l'appel qui est mauvais... J'a mis...

ReadLine(1,"D:\\Medias\\Temp\\mot.txt", Line); */ il n'y a qu'une ligne au fichier, même qu'un mot...


Mais je vais essayer ta 2ième version..
Messages postés
11
Date d'inscription
samedi 22 septembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

En tout cas merci à tous...
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Pour les 2 versions il faut que ton fichier ais plus d'une ligne...

Neo_Fr
Messages postés
11
Date d'inscription
samedi 22 septembre 2007
Statut
Membre
Dernière intervention
30 avril 2008

Merci beaucoup à toua,

J'ai pris la solution de Neo parce que c'est la première que j'ai pu lancer correctement mais merci aussi à SAKindom, en tout cas en 3 jours, j'ai appris que C c'était vacheement compliqué pour ma petite tronche...

Dark heureux d'arriver au bout...
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2