Gå til innhold

Multiline integer read fra fil


Anbefalte innlegg

Hei,

 

Skriver et storre prosjekt paa hobbybasis og har rotet meg opp i et problem som jeg ikke finner noen god losning paa. Ene delen av programmet lager en fil fyllt med integers, over flere linjer,

hver linje representerer ett array. Denne delen fungerer som den skal og produserer en fil alla denne, hvert array er representert pa sin egen linje, og kan vare av vilken som helst lengde:

 

(myfile.txt)

-----------------------------------

1 2 3 4 5 6 7 8 9 0
1 22 34 45 67 89 09 23 34
34 54 56 78
235 6 4879 390 2356 4

-----------------------------------

 

Problemet kommer naar jeg skal lese filen inn igjen, jeg har ikke funnet noen vetig maate aa gjore dette. AA lese inn hele filen til ett array gaar fint:

 

-----------------------------------

#include <stdio.h>

int ReadFile(char src[32], int tmp[])
{
int i = 0;
FILE *src_file;

 printf("***file: %s\n", src);

 if((src_file = fopen(src, "r")) == NULL)
 {
 	printf("***The src file %s does not exist!\n", src);
 }
 else
 {
 	printf("***Reading file: %s...\n", src);	

 	while((fscanf(src_file, "%i ", &tmp[i])) != EOF)	
 	{
   printf("INT %i: %i\n", i, tmp[i]);

   i++;
 	}	


                   	fclose(src_file);
 }  

return i;
}

int main()
{
char src[32] = "myfile.txt";
int tmp[8192];

ReadFile(src, tmp);

return 0;

}

-----------------------------------

 

Jeg har vurdert en av to losninger som passer med resten av koden:

- Et index der jeg kan etablere hvor '\n' befinner seg saa jeg kan bruke den for aa dele opp arrayet logisk senere.

- En losning der jeg kan stoppe aa lese inn naar jeg treffer slutten av linjen,

saa jeg kan lese videre i filen og lagre i neste array.

 

Det er viktig for programmet at hver celle i array'et inneholder hvert respektive tall,

defor vil ikke en losning der jeg bruker fgetc/fgets eller lignende virke (uten mye konverteringskode, som jeg hadde haapet aa slippe). Har vurdert en losning der jeg bruker en egendefinert "kode" etter hver avsluttet linje, men dette er ogsaa en "stygg" maate aa gjore det hele paa.

 

Er det en enkel losning der jeg fx. kan sjekke om neste verdi er en "\n" eller noe lignende?

noe alla (ignorer int problematikken, bare et eksempel):

if(tmp[i] == '\n')
{
     index[j] = i;
     j++;
}

Har noen en losning paa hvordan jeg kan etablere hvor '\n' befinner seg?

 

[ Infected ]

Lenke til kommentar
Videoannonse
Annonse
Er det en enkel losning der jeg fx. kan sjekke om neste verdi er en "\n" eller noe lignende?

noe alla (ignorer int problematikken, bare et eksempel):

if(tmp[i] == '\n')
{
     index[j] = i;
     j++;
}

Har noen en losning paa hvordan jeg kan etablere hvor '\n' befinner seg?

 

[ Infected ]

8793283[/snapback]

 

Du kan jo bruke strchr til å finne \n.

Lenke til kommentar

Hvis du ikke er kjent med antall integers som er lagret i hver rad, så må du vel kanskje uansett lese igjennom på forhånd. Kanskje ha innleste verdier lagret i en linked list også konvertere dem til array senere (eller bare bruke stl:vector :))?

 

Du bør også sørge for å sjekke størrelsen på i. Hvis denne vokser seg størren enn int tmp[8192]; så har du oppnådd en klassisk Linux og Windows sikkerhetsfeil. :D

Lenke til kommentar
Hva med å bruke den første verdien til å indikere lengden på arrayen?

Personlig liker jeg svært dårlig les til det stopper teknikker, men hvis det er mennesker som skal kunne redigere har man vel ikke noe annet valg.

8801163[/snapback]

 

Dette er nok den beste losningen paa problemet, selv om jeg personlig hadde haapet aa slippe "konfigurasjons" informasjon i filene.

 

Nei mennesker skal ikke inn i disse filene, det programmet selv som lagrer informasjon her, saa det kan fortsette igjen der det slapp senere. Derfor jeg vet all informasjon som jeg trenger naar programmet avsluttes, problemet er aa faa all denne informasjonen tilbake til programmet i neste runde...

 

Utover det er ikke buffer overflow noen stor trussel i dette programmet, paa naavarende tidspungt, og skal bli tatt haand om naar de er aktuelle :) Er plenty andre 'bugs' som jeg prioriterer forst :)

 

Forsokte aa lese inn og finne '\n' ved hjelp av strchr, men problemet som oppstod er at strchr leser inn ett tegn, selv om i denne filens tilfelle er det ikke sagt at ett tall (som blir tatt som en karater) er hele tallet, tallene kan vare opp til 8192 i storrelse, og vil nok vokse godt over det naar programmet blir mer voksent.

 

Skal sjekke ut hvordan en losning der jeg lagrer lengden av hver rekke som forste tallet i rekken. Er nok den reneste losningen, som ogsaa kan dynamisk utvide seg som programmet vokser.

 

Takk for alle svar!

[ Infected ]

Endret av [Infected]
Lenke til kommentar
hvis ikke mennesker skal bruke disse filene, hvorfor skirver du ikke bare en binærfil da? mye raskere, og enklere både å lese og skrive.

8803273[/snapback]

 

Filen blir skrevet som en binarfil, (ab), men problemet er fortsatt det samme.

(den blir bare skrevet en verdi av gangen...)

 

Om jeg skriver inn alle verdiene fra arrayet i ett jafs, hvordan kan jeg da faa det tilbake om jeg ikke vet hvor stort det er?

 

 

MvH

[ Infected ]

Lenke til kommentar
,07/06-2007 : 12:29]...

Om jeg skriver inn alle verdiene fra arrayet i ett jafs, hvordan kan jeg da faa det tilbake om jeg ikke vet hvor stort det er?

 

MvH

[ Infected ]

8803563[/snapback]

 

Vel hvis du ikke vet hvor stor den er så må du ha et eller annet som sier at arrayen stopper her. som f. eks. vanlige 0- terminerte stringer.

 

Hvis du bruker binære tall kan du bare parse det slik som dette. INT_MAX brukes til å skille arrayene fra hverandre.

 

Klikk for å se/fjerne innholdet nedenfor
#include <malloc.h>
#include "LIMITS.H"
#include <memory.h>

int main()
{
int	pIntArray[] = {1,2,INT_MAX,
       1,2,33,INT_MAX};
int  SizeOfArray = sizeof(pIntArray)/sizeof(int);

int* StartOfSubArray = (int*)pIntArray;
for(int i = 0;i<SizeOfArray;i++)
{
 if(pIntArray[i] == INT_MAX)
 {
 	int SizeOfSubArray = &pIntArray[i]-StartOfSubArray;
 	int* SubArray = new int [SizeOfSubArray];
 	memcpy(SubArray,StartOfSubArray,SizeOfSubArray*sizeof(int));
       //lagre subarray peker...
 	delete SubArray; //eller bare slett
 	StartOfSubArray = &pIntArray[i+1];
 }
}
   return 0;
}

Endret av Giddion
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...