Lecture d'un fichier txt

Résolu
Darklecon Messages postés 11 Date d'inscription samedi 22 septembre 2007 Statut Membre Dernière intervention 30 avril 2008 - 20 oct. 2007 à 10:29
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 - 21 oct. 2007 à 23:01
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

Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 oct. 2007 à 16:16
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
3
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 oct. 2007 à 16:56
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
3
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
20 oct. 2007 à 12:18
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.
0
Darklecon Messages postés 11 Date d'inscription samedi 22 septembre 2007 Statut Membre Dernière intervention 30 avril 2008
20 oct. 2007 à 12:30
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é...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 oct. 2007 à 14:27
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++ (@++)<!--
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 oct. 2007 à 14:43
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
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 oct. 2007 à 15:50
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++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 oct. 2007 à 16:41
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).
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 oct. 2007 à 16:47
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++ (@++)<!--
0
Darklecon Messages postés 11 Date d'inscription samedi 22 septembre 2007 Statut Membre Dernière intervention 30 avril 2008
20 oct. 2007 à 16:57
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..
0
Darklecon Messages postés 11 Date d'inscription samedi 22 septembre 2007 Statut Membre Dernière intervention 30 avril 2008
20 oct. 2007 à 16:59
En tout cas merci à tous...
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 oct. 2007 à 17:01
Pour les 2 versions il faut que ton fichier ais plus d'une ligne...

Neo_Fr
0
Darklecon Messages postés 11 Date d'inscription samedi 22 septembre 2007 Statut Membre Dernière intervention 30 avril 2008
20 oct. 2007 à 19:03
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...
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
21 oct. 2007 à 23:01
0
Rejoignez-nous