Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2021-01-07, 17:05
  #1
Medlem
Tjena,

Jag håller på och lär mig lite programmering i C.
Det ligger en csv under min C disk som jag skrivit in "testar + radnummer," några rader nedåt.
Dvs:
testar1,
testar2,
testar3, osv osv.

Jag vill läsa de 5 senaste raderna i denna filen, alltså börja längst ned och gå uppåt. Så att output blir:
testar5
testar4
testar3
testar2
testar1

Men jag får inte detta att funka. Den output jag får blir:

testar1
testar1
testar1
testar1
testar1

Vad har jag gjort för fel? Finns det något annat sätt att göra det på? har googlat och läst i timmar men tycker mig inte finna svaren på mina frågor.



min kod:
Citera
2021-01-07, 17:26
  #2
Moderator
Protons avatar
Citat:
Ursprungligen postat av Hardnippel
Tjena,

Jag håller på och lär mig lite programmering i C.
Det ligger en csv under min C disk som jag skrivit in "testar + radnummer," några rader nedåt.
Dvs:
testar1,
testar2,
testar3, osv osv.

Jag vill läsa de 5 senaste raderna i denna filen, alltså börja längst ned och gå uppåt. Så att output blir:
testar5
testar4
testar3
testar2
testar1

Men jag får inte detta att funka. Den output jag får blir:

testar1
testar1
testar1
testar1
testar1

Vad har jag gjort för fel? Finns det något annat sätt att göra det på? har googlat och läst i timmar men tycker mig inte finna svaren på mina frågor.



min kod:
Länge sen jag skrev nåt i C, men den där algoritmen ser ju aningen sned ut.

Du har ju en loop och det är ju helt fine, men varför öppnar du filen för läsning för varje varv i denna loop?

Det borde ju vara så att först öppnar du filen
Sen med hjälp av din loop läser du in en rad från filen och gör något med den.
När du är klar med din loop stänger du filen.
Citera
2021-01-07, 17:37
  #3
Medlem
Oklart vad fseek gör i det där fallet.

Citat:
Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability).

Ett mer standardiserat och portabelt sätt att lösa det borde vara att läsa igenom filen, och spara de fem sista raderna.
Citera
2021-01-07, 17:45
  #4
Medlem
Citat:
Ursprungligen postat av mulpac
Oklart vad fseek gör i det där fallet.



Ett mer standardiserat och portabelt sätt att lösa det borde vara att läsa igenom filen, och spara de fem sista raderna.


Tjena,

Tanken var att jag skulle slippa söka igenom hela filen, ponera att det skulle finnas 10 000 rader i filen.
Vore ju smidigare att börja nedifrån och sedan med hjälp av en for loop iterera offseten tänkte jag.

"Description
The C library function int fseek(FILE *stream, long int offset, int whence) sets the file position of the stream to the given offset."
Citera
2021-01-07, 17:50
  #5
Medlem
Citat:
Ursprungligen postat av Hardnippel
Tjena,

Tanken var att jag skulle slippa söka igenom hela filen, ponera att det skulle finnas 10 000 rader i filen.
Vore ju smidigare att börja nedifrån och sedan med hjälp av en for loop iterera offseten tänkte jag.

"Description
The C library function int fseek(FILE *stream, long int offset, int whence) sets the file position of the stream to the given offset."

Ja, fseek i sig funkar troligen bra, men just SEEK_END verkar inte portabelt.
Vet faktiskt inte riktigt hur man läser filer bakvägen på ett effektivt sätt. Brukar "fuska" och använda tail när jag behöver de sista raderna, för den är effektiv. Den borde förvisso vara skriven i C, så det går att kolla hur de gjort.
__________________
Senast redigerad av mulpac 2021-01-07 kl. 18:06.
Citera
2021-01-07, 19:19
  #6
Medlem
Har labbat lite med fseek funktionen, den fungerar inte riktigt som jag tänkte mig.

För det första verkar det som att man måste iterera åt det andra hållet, dvs negativt:
https://stackoverflow.com/questions/...k-and-seek-end


Gjorde om min kod till:

Detta gjorde att de sista 5 raderna blev printade. Problemet verkar ju vara att jag måste veta hur stor varje rad är i bytes och på något vis backa så många rader?
Citera
2021-01-07, 19:48
  #7
Medlem
Citat:
Ursprungligen postat av Hardnippel
Detta gjorde att de sista 5 raderna blev printade. Problemet verkar ju vara att jag måste veta hur stor varje rad är i bytes och på något vis backa så många rader?

Här finns en rätt intressant diskussion på temat
https://stackoverflow.com/questions/...ast-line-first
Citera
2021-01-07, 22:35
  #8
Medlem
Backa tills du hittar nyradstecknet för respektive rad.
Citera
2021-01-08, 11:18
  #9
Medlem
Citat:
Ursprungligen postat av mulpac
Här finns en rätt intressant diskussion på temat
https://stackoverflow.com/questions/...ast-line-first


Läste det du länkade och fick ett humm om vad jag egentligen letade efter, och hittade flertal länkar till trådar där folk velat ungefär samma som jag. Stötte t.ex på denna.

Dock inte fått det att fungera ännu..
Citera
2021-01-08, 11:24
  #10
Medlem
Citat:
Ursprungligen postat av isolering
Backa tills du hittar nyradstecknet för respektive rad.

Har försökt med följande kod:


Tanken är att stega igenom från slutet och gå bakåt tills dess att programmet stöter på en new line "0x0a".
När den gör det läser programmet från den pointern tills dess att raden tar slut med hjälp av "fgets".

Blir dock bara en massa kvadrater i terminalen när jag gör på detta viset, så något utförs inte korrekt.
Citera
2021-01-08, 11:41
  #11
Medlem
Citat:
Ursprungligen postat av Hardnippel
Har försökt med följande kod:


Tanken är att stega igenom från slutet och gå bakåt tills dess att programmet stöter på en new line "0x0a".
När den gör det läser programmet från den pointern tills dess att raden tar slut med hjälp av "fgets".

Blir dock bara en massa kvadrater i terminalen när jag gör på detta viset, så något utförs inte korrekt.
Tog du bort while loopen? Nu läses väl bara absolut sista tecknet en gång.
När du backar kan du ju ha en variabel med antalet hittade 0x0a, när den har värdet 5 läser du framlänges till eof.
Citera
2021-01-08, 15:38
  #12
Medlem
Citat:
Ursprungligen postat av isolering
Tog du bort while loopen? Nu läses väl bara absolut sista tecknet en gång.
När du backar kan du ju ha en variabel med antalet hittade 0x0a, när den har värdet 5 läser du framlänges till eof.


Jag testade fseek funktionen manuellt genom att skriva offseten själv, och funktionen hittade inget förrän på offset = 5.

Så jag satte i = 5 för att börja iterera från 5, och fram tills det blev en new line.
Detta resulterade i följande kod:


Nu får jag åtminstone ut något, men jag inte riktigt sätta fingret på vad som händer.
Terminalen printar ut:


Varför hittar den inte "," och "7"?
Varför printar den en 12a men inget mer? 12an borde vara 7an. Kan inte 7 behandlas som en char?
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback