Amir Skrevet 11. november 2003 Del Skrevet 11. november 2003 Har et lite problem med en oppgave vi har fått på skolen. Skal lage et "tail" program som skriver ut de n siste linjene i en fil. Det skal skrives i C++. Jeg har fått laget programmet og alt fungerer, men det jeg har problemer med er; n = argv[2]; // antall linjer som skal skrives ut char** p = new char*[n]; for ( int i = 0; i < n; i++ ) { p = new int[1024]; // her ligger problemet. } og det er her problemet kommer. Det er vanskelig å vite om en linje ikke inneholder mer enn 1024 char...og hvordan løser jeg problemet?. Jeg bruker dobbel pekeren ( p ) som en sirkulær kø. NB! Vi får ikke lov til å lese en linje mer enn 1 gang! og heller ikke lese mer enn n linjer i minnet. Får heller ikke lov til å bruke noen av funksjonene i STL ( som vector, string og tilsvarende )... Mvh - Amir- Lenke til kommentar
daysleper Skrevet 11. november 2003 Del Skrevet 11. november 2003 ..hva med å ikke lese inn en hel linje (som du ikke kan vite hvor lang er på forhånd) - men i stedet lese inn f.eks. ett og ett tegn om gangen? Lenke til kommentar
Amir Skrevet 11. november 2003 Forfatter Del Skrevet 11. november 2003 jo..tenkte på det, men hvordan/hvor skal jeg ta vare på tegnene i mellomtiden slik at jeg senere allokerer minne.... Lenke til kommentar
A_N_K Skrevet 11. november 2003 Del Skrevet 11. november 2003 Siden du ikke får lov til å bruke vector/string, kan du vel bruke C-funksjonen realloc, og stadig øke bufferen din med en passende mengde? Du kan sikkert sjekke ut kilden til std::string og se hvordan den øker sin størrelse. Lenke til kommentar
jalemo Skrevet 10. desember 2003 Del Skrevet 10. desember 2003 men i stedet lese inn f.eks. ett og ett tegn om gangen? Å lese inn en linje som inneholder 1024 tegn krever 1 system call. Å lese inn denne linjen ett og ett tegn om gangen krever 1024 system calls. Det finnes grenser for hvor mye ressurser man trenger å sløse. Jalemo Lenke til kommentar
daysleper Skrevet 10. desember 2003 Del Skrevet 10. desember 2003 Hva med en linje som inneholder mer enn 1024 tegn? Men ja; det beste hadde helt klart vært å lese inn mer enn ett og ett tegn om gangen ved å bruke buffere på f.eks. 1024 tegn. Lenke til kommentar
Vaughn Skrevet 12. desember 2003 Del Skrevet 12. desember 2003 Ta en titt på getline(3) funksjonen, dersom du får bruke denne - den leser en linje av gangen, og allokerer minne selv. Den er imidlertid en GNUting, og finnes ikke i Windows. (Uten å bruke libiberty, altså.) Ellers kunne du bruke read(2)-kallet, lese 1024 bokstaver ad gangen og utvide strengen etterhvert. Du kunne også lage en lenket liste bestående av strenger på 1024 chars. read(2) returnerer antall tegn lest, men stopper ikke ved linjeskift; du må bufre det selv. For å stoppe ved linjeskift *må* du enten lese ett tegn av gangen, eller (bedre) bruke ikke-blokkerende IO - men da kan du få linjeskiftet + litt av neste setning, og må bufre. Standard libc har ingen funksjoner for dette, derfor bruken av read-systemkallet; oppførselen til fgetc(3) kan innvolvere et systemkall per kall - ingen garantier der. Hvis du velger å utvide strengen du leser til etterhvert bør du forøvrig doble den hver gang; da får du O(N log N) hastighet, mens en konstant økning vil gi O(N^2). Lenke til kommentar
jalemo Skrevet 18. desember 2003 Del Skrevet 18. desember 2003 For å stoppe ved linjeskift *må* du enten lese ett tegn av gangen, eller (bedre) bruke ikke-blokkerende IO The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error. fgets() kan lese fra alle FILE *streams. read() tar en file descriptor som argument, og det er null problem å få gjort om denne fd'en til en FILE *stream med fdopen() eller lignende. En annen mulighet er å lese inn alt i en dynamisk allokert char peker og så dele opp denne strengen etter newlines. Det er ikke så vanskelig å få til noe her, det dummeste man gjør er å lese inn en fil char for char, det er lite trivelig med store filer. Jale Lenke til kommentar
kjetil7 Skrevet 19. desember 2003 Del Skrevet 19. desember 2003 (endret) fgets() er løsningen. Ellers må han lese et og et tegn. Endret 19. desember 2003 av kjetil7 Lenke til kommentar
GeirGrusom Skrevet 22. desember 2003 Del Skrevet 22. desember 2003 ...men hvorfor bruker du p = new int[1024] når p er deklarert som char**? Bruk malloc istedet, mye enklere. dessuten skal det ikke være p = new char[1024]? Lenke til kommentar
Duronator Skrevet 22. desember 2003 Del Skrevet 22. desember 2003 Jeg fant at et lite tail program jeg lagde en gang, så her er det: Gikk litt fort og gæli men jaja, gidder ikke fikse så mye på det... #include <stdio.h> #include <unistd.h> #include <fcntl.h> #define BUFFERSIZE 4096 static int fd; int printwholefile = 0; int print_tail(int); int main(int argc, char **argv) { int pos = 0; if( argc < 2) { printf("Usage: %s <filename>\n", argv[0]); exit(1); } if( (fd = open(argv[1], O_RDONLY)) == -1) { perror(argv[1]); exit(1); } print_tail(10); close(fd); return 0; } int print_tail(int lin) { int num_bytes, lines, bytesfrombuf, line, i, printfromhere; num_bytes = lines = bytesfrombuf = line = i = printfromhere = 0; char buffer[BUFFERSIZE]; while( (num_bytes = read(fd, buffer, BUFFERSIZE)) > 0) { for(bytesfrombuf = 0; bytesfrombuf < num_bytes; bytesfrombuf++) { if(buffer[bytesfrombuf] == '\n') lines++; } buffer[0] = '\0'; } printf("Lines in file: %d\n", lines); lseek(fd, 0, SEEK_SET); if(lines < lin) while( read(fd, buffer, BUFFERSIZE) > 0) printf("%s", buffer); while( (num_bytes = read(fd, buffer, BUFFERSIZE)) > 0) { if( !printfromhere ) { for( bytesfrombuf = 0; bytesfrombuf < num_bytes; bytesfrombuf++) { if( buffer[bytesfrombuf] == '\n') { line++; if( line == (lines-lin)) { printfromhere = 1; for ( i = bytesfrombuf; i < num_bytes; i++ ) { printf("%c", buffer[i]); } break; } } } } else printf("%s", buffer); buffer[0] = '\0'; } return 0; } Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå