goncalomsdias Posted June 6, 2012 at 03:25 PM Report Share #460933 Posted June 6, 2012 at 03:25 PM (edited) Boa tarde! Preciso de ler um ficheiro e conseguir guardar os valores de cada linha num array. O problema é que o ficheiro vai ser bastante grande por isso não posso declarar o tamanho do array. Já faz algum tempo que não programo em C, por isso estou meio perdido nisto... #include <stdio.h> #include <stdlib.h> int main (void) { FILE *fp; char filename[100]; char* data; puts("Insert file name to open."); gets(filename); fp = fopen(filename,"r"); fseek(fp, 0L, SEEK_END); int sz = ftell(fp); //You can then seek back to the beginning: fseek(fp, 0L, SEEK_SET); data = malloc(sz); if(fp==NULL) { printf("Cant open file! %s\n",filename); exit(1); } else { // calucate the size of the file. fseek(fp, 0L, SEEK_END); int sz = ftell(fp); //seek back to the beginning: fseek(fp, 0L, SEEK_SET); data = malloc(sz); //fread(data ,sz, 1, fp); size_string = strlen(data); //printf("%d",&size_string); while(fgets(data,sz,fp)!=NULL) { } } } Actualmente tenho este código, mas não sei o que fazer para guardar cada linha no array... Se puderem dar umas dicas ficava muito agradecido. Edited June 6, 2012 at 05:46 PM by pmg LP adicionada ao GeSHi existente Link to comment Share on other sites More sharing options...
pikax Posted June 6, 2012 at 03:33 PM Report Share #460937 Posted June 6, 2012 at 03:33 PM Podes ler o ficheiro todo e saber quantas linhas tem e alocar dinamicamente o array. Ou tambem podes ter o numero de linhas no inicio do ficheiro. Tambem podes ter um array com um tamanho predefinido e depois se tiver cheio crias outro e copias o valor do array Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast." Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted June 6, 2012 at 03:48 PM Report Share #460944 Posted June 6, 2012 at 03:48 PM saber o tamanho do ficheiro nunca é indicativo do número de linhas, exemplo linha 1 bem compridinha\n linha 2\n linha 3 ... ui que comprida que ela é ... até chega quase ao fundo aqui da caixa \n consegues dizer quantas linhas tem este ficheiro só pelo número de bytes ?? se não sabes o número de linhas só tens duas opções: - declaras um array demasiado grande sabendo que nunca será completamente preenchido - usas memória dinâmica IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 6, 2012 at 04:16 PM Author Report Share #460965 Posted June 6, 2012 at 04:16 PM declarar um array demasiado grande está fora de questão, porque os ficheiros podem ser mesmo grandes... Como o pikax disse, não é possível usar o fgets para ler linha a linha, e ao mesmo tempo ter um contador a somar o número de linhas? Com esse número de linhas já é possível saber qual o tamanho que é necessário para o array Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted June 6, 2012 at 04:19 PM Report Share #460969 Posted June 6, 2012 at 04:19 PM declarar um array demasiado grande está fora de questão, porque os ficheiros podem ser mesmo grandes... Como o pikax disse, não é possível usar o fgets para ler linha a linha, e ao mesmo tempo ter um contador a somar o número de linhas? Com esse número de linhas já é possível saber qual o tamanho que é necessário para o array para isso terias de ler o ficheiro 2 vezes ... tu próprio disseste que os ficheiros seriam mesmo grandes .... deixa-te de malandrices e toca a criar uma lista ligada ou algo do género ... typedef struct ListaElem { char * line; struct ListaElem * next; } ListaElem; typedef struct Lista { size_t quantity; ListaElem * first; ListaElem * last; } Lista; IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
pikax Posted June 6, 2012 at 04:21 PM Report Share #460970 Posted June 6, 2012 at 04:21 PM declarar um array demasiado grande está fora de questão, porque os ficheiros podem ser mesmo grandes... que tamanhos estas a falar?? Como o pikax disse, não é possível usar o fgets para ler linha a linha, e ao mesmo tempo ter um contador a somar o número de linhas? Com esse número de linhas já é possível saber qual o tamanho que é necessário para o array sim podes fazer isso. Ja' agora, porque que nao usas uma lista?? Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast." Link to comment Share on other sites More sharing options...
bsccara Posted June 6, 2012 at 04:25 PM Report Share #460976 Posted June 6, 2012 at 04:25 PM O código que postaste já faz isso (duas vezes): obtém o tamanho do ficheiro com fseek/ftell, aloca um bloco de memória desse tamanho + 1, preenche-o com um fread do ficheiro todo e mete um 0 no final do bloco, usa a função strtok para partir o bloco em linhas (usando os caracteres \r e \n como separadores) e guarda os ponteiros para cada linha (devolvidos pela strtok, se o comprimentto dessa string não fôr 0) num outro bloco de memória (array de ponteiros), que podes aumentar com o realloc quando estiver cheio (aumenta-o em blocos, não ponteiro a ponteiro). Neste caso irás gastar apenas um ponteiro por cada linha (4 bytes), para além da memória necessária para as linhas em si. 1 Report Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 6, 2012 at 04:30 PM Author Report Share #460979 Posted June 6, 2012 at 04:30 PM neste momento tenho 1 ficheiro com mais de 10000 linhas. Mas o objectivo é ficar preparado para lidar com ficheiros maiores que isso, e com mais que 1 ficheiro desses. O código que postaste já faz isso (duas vezes): obtém o tamanho do ficheiro com fseek/ftell, aloca um bloco de memória desse tamanho + 1, preenche-o com um fread do ficheiro todo e mete um 0 no final do bloco, usa a função strtok para partir o bloco em linhas (usando os caracteres \r e \n como separadores) e guarda os ponteiros para cada linha (devolvidos pela strtok, se o comprimentto dessa string não fôr 0) num outro bloco de memória (array de ponteiros), que podes aumentar com o realloc quando estiver cheio (aumenta-o em blocos, não ponteiro a ponteiro). Neste caso irás gastar apenas um ponteiro por cada linha (4 bytes), para além da memória necessária para as linhas em si. Quando chegar a casa ja vou tentar isso e depois digo algo. Link to comment Share on other sites More sharing options...
pikax Posted June 6, 2012 at 04:31 PM Report Share #460980 Posted June 6, 2012 at 04:31 PM falame em Bytes, KB, MB e GB, o numero de linhas cheja a ser um pouco relativo, se tiveres um caracter por linha seria um ficheiro de 10000Bytes que e' um pouco menos de 10~9KB, achas isso grande?? Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast." Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 6, 2012 at 04:35 PM Author Report Share #460985 Posted June 6, 2012 at 04:35 PM sim, é pouco relativo. O tamanho em si não será muito grande. Poucos Mb's, provavelmente na ordem dos 10mb. Link to comment Share on other sites More sharing options...
pikax Posted June 6, 2012 at 04:39 PM Report Share #460987 Posted June 6, 2012 at 04:39 PM nao concegues encaixar 10MB na memoria??? se tu declares um array gigante! char *array[9999999]; este array vazio ira' ocupar 9999999*sizeof(char*) Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast." Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 6, 2012 at 04:42 PM Author Report Share #460989 Posted June 6, 2012 at 04:42 PM bem, conseguir consigo, não me parece é que seja a maneira indicada para o fazer lol Link to comment Share on other sites More sharing options...
pmg Posted June 6, 2012 at 05:51 PM Report Share #461007 Posted June 6, 2012 at 05:51 PM (edited) Eu tenho outra sugestao, se for possivel: em vez de leres o ficheiro todo para um array e tratares os dados como um todo, les e tratas cada linha isoladamente num ciclo. ou seja, em vez de // pseudo codigo while (fgets(linha)) { strcpy(array[nlinhas++], linha); } for (i = 0; i < nlinhas; i++) { tratalinha(array[i]); } experimenta assim // pseudo codigo while (fgets(linha)) { tratalinha(linha); } Edited June 6, 2012 at 05:52 PM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código! Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 6, 2012 at 06:38 PM Author Report Share #461020 Posted June 6, 2012 at 06:38 PM Eu tenho outra sugestao, se for possivel: em vez de leres o ficheiro todo para um array e tratares os dados como um todo, les e tratas cada linha isoladamente num ciclo. ou seja, em vez de // pseudo codigo while (fgets(linha)) { strcpy(array[nlinhas++], linha); } for (i = 0; i < nlinhas; i++) { tratalinha(array[i]); } experimenta assim // pseudo codigo while (fgets(linha)) { tratalinha(linha); } Isso acho que não vai dar, porque depois vou precisar de manipular uma das colunas dentro da linha, para todas as linhas... Link to comment Share on other sites More sharing options...
goncalomsdias Posted June 8, 2012 at 06:05 PM Author Report Share #461516 Posted June 8, 2012 at 06:05 PM É só para agradecer a ajuda que me deram.. Para já acabei por utilizar a sugestão do pmg e leio o ficheiro linha a linha, e conforme vou lendo vou fazendo as alterações que pretendo. Para já está a resultar bem, mais para a frente vamos ver lol Obrigadol. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now