Carloz Posted January 6, 2008 at 06:43 PM Report Share #158301 Posted January 6, 2008 at 06:43 PM Boas...cá estou mais uma vez. É o seguinte...tenho de fazer um programa final para a cadeira de C, e o objectivo é fazer um sistema de gestão de viaturas para uma auto-estrada. Decidi criar um tópico geral para ir postando duvidas/dificuldades que surgam, para não estar sempre a criar novos tópicos. Neste momento o meu problema é a leitura de dados. Os carros que passam na auto-estrada são lidos através de um ficheiro de dados com a seguinte estrutura: CÓDIGO RETIRADO! Nota: "_clean();" e "_pause();" são funções que limpam o ecrâ e esperam por uma tecla respectivamente. EDIT: Código Actualizado! Ainda assim não está bem. Quando faço o printf para mostrar as informações do carro (ID, classe...), sai tudo marado, com ints negativos e nao sei que... Questões: - Quando lemos dados de um ficheiro binário, os dados são "convertidos para linguagem humana" certo? Não permanecem como 0's e 1's pois não? - Uma vez que o ficheiro contêm inteiros e caracteres, não sei como fazer para guardar os dados. Mas se o ficheiro é binário entao isto nao seria necessário certo? É mesmo necessário guardar os dados, uma vez que estes ficam em memória após o "open"? - O meu objectivo é organizar os dados por estructuras mas isto do binário confunde-me e não sei como o fazer. Conclusão: A minha dificuldade está em ler e manipular a informação a partir de um ficheiro binário. P.S. Se quiserem mais informações sobre o trabalho podem ver aqui: - Enunciado (PDF) - Pacote de dados (ZIP) - Ficheiros alternativos para manipular ficheiros binários (ZIP) Agradeço a vossa ajuda Cumprimentos "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
TheDark Posted January 7, 2008 at 02:02 AM Report Share #158370 Posted January 7, 2008 at 02:02 AM - Quando lemos dados de um ficheiro binário, os dados são "convertidos para linguagem humana" certo? Não permanecem como 0's e 1's pois não? Ora... como responder a isto...? Num computador, TUDO são dados binários, ou zeros e uns. O computador é que os interpreta de maneira a ser-nos (humanos) mais fácil ler esses dados. Deves saber que 1101000 em binário é 104 em decimal, certo? Se interpretares isso como um código ASCII, vais obter o caracter 'h'. É só isto que o computador faz. - Uma vez que o ficheiro contêm inteiros e caracteres, não sei como fazer para guardar os dados. Mas se o ficheiro é binário entao isto nao seria necessário certo? É mesmo necessário guardar os dados, uma vez que estes ficam em memória após o "open"? No que toca aos ficheiros propriamente ditos, não há ficheiros "não binários". Os ficheiros são todos armazenados como conjuntos de bits (organizados em bytes). Quando são lidos, a interpretação é que muda. Quando escreves num ficheiro de texto, as funções de escrita convertem o '\n' para o formato adequado a cada sistema operativo. Quanto à parte de ficarem em memória, não sei se percebi muito bem, mas quando terminas o programa tudo o que está em memória vai ao ar. - O meu objectivo é organizar os dados por estructuras mas isto do binário confunde-me e não sei como o fazer. Se vais armazenar estruturas de dados num ficheiro, o mais acertado é utilizar o modo binário. Isto porque para guardar uma estrutura (que não contenha apontadores) num ficheiro é tão simples quanto fazer fwrite(&estrutura, sizeof(ESTRUTURA), 1, ficheiro); e para ler fread(&estrutura, sizeof(ESTRUTURA), 1, ficheiro); onde ESTRUTURA é o typedef da struct, e estrutura é uma "instância" de ESTRUTURA. Desaparecido. Link to comment Share on other sites More sharing options...
Carloz Posted January 7, 2008 at 02:39 PM Author Report Share #158413 Posted January 7, 2008 at 02:39 PM Antes de mais obrigado por responderes TheDark. 😄 Ora... como responder a isto...? Num computador, TUDO são dados binários, ou zeros e uns. O computador é que os interpreta de maneira a ser-nos (humanos) mais fácil ler esses dados. Deves saber que 1101000 em binário é 104 em decimal, certo? Se interpretares isso como um código ASCII, vais obter o caracter 'h'. É só isto que o computador faz. O que eu quis dizer, é que se estivermos a ler de um ficheiro .txt, é diferente de estarmos a ler de um ficheiro .dat. A minha dúvida era se ao lermos um ficheiro .dat em binário, se o conteúdo é ou não automaticamente traduzido para código ASCII. É que assim o tratamento dos dados seria diferente certo? Por exemplo...um ficheiro que contenha uma linha com "1101000". Se eu ler essa linha, puser numa var, e fizer um printf, o que é que me aparece no ecrâ? Aparece "1101000" ou "h"? Essa era a minha questão 😄 No que toca aos ficheiros propriamente ditos, não há ficheiros "não binários". Os ficheiros são todos armazenados como conjuntos de bits (organizados em bytes). Quando são lidos, a interpretação é que muda. Quando escreves num ficheiro de texto, as funções de escrita convertem o '\n' para o formato adequado a cada sistema operativo. Quanto à parte de ficarem em memória, não sei se percebi muito bem, mas quando terminas o programa tudo o que está em memória vai ao ar. A minha questão era se eu tinha acesso ao conteúdo lido, apenas através do "fopen" (na memória) ou se era necessário fazer um "fread" (para uma var/estructura). Mas pelo que percebi tenho de meter a informação numa "struct". Se vais armazenar estruturas de dados num ficheiro, o mais acertado é utilizar o modo binário. Isto porque para guardar uma estrutura (que não contenha apontadores) num ficheiro é tão simples quanto fazer fwrite(&estrutura, sizeof(ESTRUTURA), 1, ficheiro); e para ler fread(&estrutura, sizeof(ESTRUTURA), 1, ficheiro); onde ESTRUTURA é o typedef da struct, e estrutura é uma "instância" de ESTRUTURA. Isso é o que eu ando a tentar fazer, mas sem sucesso. //ESTRUTURA struct Carro { int ID; int classe; int port_in; int port_out; char port_in_time[TIME_LENGHT]; char port_out_time[TIME_LENGHT]; }; struct Carro carro; //"instância" for (n=0; n<nt; n++) { fread(&carro, sizeof(carro), 1, fp); //LÊ DADOS printf("\n\nID: %d \n Classe: %d \n Entrada: %d \n SaÃda: %d \n Hora de entrada: %s \n Hora de SaÃda: %s", carro.ID, carro.classe, carro.port_in, carro.port_out, carro.port_in_time, carro.port_out_time); getchar(); } Esse é o código que tenho. O que é que acontece? Ele lê linha a linha e mete na estructura no devido lugar (ID, classe...) certo? Então e o separador ou lá o que é? É que o ficheiro antes de apresentar os dados de cada carro tem um "1" antes...excepto no final que tem "0". 1 -> SEPARADOR 123456 -> IDENTIFICADOR VIA VERDE 2 -> CLASSE DA VIATURA 1 -> PORTAGEM DE ENTRADA 2 -> PORTAGEM DE SAÍDA 19h 3m 23s -> HORA DE ENTRADA 19h 41m 52s -> HORA DE SAÍDA Ou seja...ele deveria ler a 1ª linha e colocá-la em carro.ID, a 2ª linha e colocá-la em carro.classe...e por ai. Certo? Contudo, quando faço o printf com os dados que estou a meter na estructura aparecem-me números enormes e por vezes negativos (tudo marado ^^). Isto porque para guardar uma estrutura (que não contenha apontadores) num ficheiro é tão simples quanto fazer O que queres dizer com isso de não conter apontadores? E já agora mais uma questão: - Qual a diferença entre: typedef struct ESTRUCTURA{ int algo; } TYPEDEF_ESTRUCTURA; e struct ESTRUCTURA{ int algo; }; Obrigado...e desculpem a extensão do post 😛 Cumps "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
TheDark Posted January 8, 2008 at 04:30 PM Report Share #158659 Posted January 8, 2008 at 04:30 PM Antes de mais obrigado por responderes TheDark. 😄 De nada 😄 O que eu quis dizer, é que se estivermos a ler de um ficheiro .txt, é diferente de estarmos a ler de um ficheiro .dat. A minha dúvida era se ao lermos um ficheiro .dat em binário, se o conteúdo é ou não automaticamente traduzido para código ASCII. É que assim o tratamento dos dados seria diferente certo? Por exemplo...um ficheiro que contenha uma linha com "1101000". Se eu ler essa linha, puser numa var, e fizer um printf, o que é que me aparece no ecrâ? Aparece "1101000" ou "h"? Essa era a minha questão 😄 Se escreveres o caracter 'h' para um ficheiro binário e de seguida abrires esse ficheiro, o que vais ver é 'h', e não "1101000". Se abrires o mesmo ficheiro num editor hexadecimal, vais ver dum lado a sua representação como caracter ('h') e do outro a sua representação em hexa ("68"). Isto é complicado de explicar rapidamente, mas os dados que ficam no ficheiro são exactamente os mesmos, mais uma vez a interpretação é que é diferente. Se leres o caracter 'h' de um ficheiro para um char c, ao fazeres printf("%c", c); vai ser impresso o caracter 'h'. Se fizeres printf("%X", (int)c); ele vai imprimir "68"; se fizeres printf("%d", (int)c); ele imprime "104". Tudo depende da interpretação 😛 A minha questão era se eu tinha acesso ao conteúdo lido, apenas através do "fopen" (na memória) ou se era necessário fazer um "fread" (para uma var/estructura). Mas pelo que percebi tenho de meter a informação numa "struct". Pois, tinha percebido mal a pergunta. Não tens que meter numa estrutura, mas quando se trata de um ficheiro em modo binário dá mais jeito! Isso é o que eu ando a tentar fazer, mas sem sucesso. //ESTRUTURA struct Carro { int ID; int classe; int port_in; int port_out; char port_in_time[TIME_LENGHT]; char port_out_time[TIME_LENGHT]; }; struct Carro carro; //"instância" for (n=0; n<nt; n++) { fread(&carro, sizeof(carro), 1, fp); //LÊ DADOS printf("\n\nID: %d \n Classe: %d \n Entrada: %d \n SaÃda: %d \n Hora de entrada: %s \n Hora de SaÃda: %s", carro.ID, carro.classe, carro.port_in, carro.port_out, carro.port_in_time, carro.port_out_time); getchar(); } Esse é o código que tenho. O que é que acontece? Ele lê linha a linha e mete na estructura no devido lugar (ID, classe...) certo? Então e o separador ou lá o que é? É que o ficheiro antes de apresentar os dados de cada carro tem um "1" antes...excepto no final que tem "0". 1 -> SEPARADOR 123456 -> IDENTIFICADOR VIA VERDE 2 -> CLASSE DA VIATURA 1 -> PORTAGEM DE ENTRADA 2 -> PORTAGEM DE SAÍDA 19h 3m 23s -> HORA DE ENTRADA 19h 41m 52s -> HORA DE SAÍDA Ou seja...ele deveria ler a 1ª linha e colocá-la em carro.ID, a 2ª linha e colocá-la em carro.classe...e por ai. Certo? Contudo, quando faço o printf com os dados que estou a meter na estructura aparecem-me números enormes e por vezes negativos (tudo marado ^^). Não tinha visto que tinhas o ficheiro com esse conteúdo. Ou melhor, tinha visto e por alguma razão ignorei 😄 Nesse caso, o melhor é abrires o ficheiro em modo texto. Depois tens que ler linha a linha e colocar o conteúdo da mesma em cada um dos campos da estrutura. O fscanf ajuda muito 😄 O que queres dizer com isso de não conter apontadores? No teu caso não faz diferença, porque não tens apontadores na estrutura, e porque não vais guardar em modo binário. Mas no caso de teres char* em vez de char[] para os campos time, terias que arranjar maneira de guardar o texto apontado pelos campos em vez dos endereços de memória, porque depois quando fosses ler irias ler endereços de memória em vez de texto. E já agora mais uma questão: - Qual a diferença entre: typedef struct ESTRUCTURA{ int algo; } TYPEDEF_ESTRUCTURA; e struct ESTRUCTURA{ int algo; }; Com typedef struct ESTRUCTURA{ int algo; } TYPEDEF_ESTRUCTURA; irias declarar uma variável deste tipo com TYPEDEF_ESTRUCTURA carro; enquanto que da outra maneira irias declarar como declaraste no teu código: struct ESTRUCTURA carro; Desaparecido. Link to comment Share on other sites More sharing options...
Carloz Posted January 8, 2008 at 11:26 PM Author Report Share #158777 Posted January 8, 2008 at 11:26 PM Não tinha visto que tinhas o ficheiro com esse conteúdo. Ou melhor, tinha visto e por alguma razão ignorei 😛 Nesse caso, o melhor é abrires o ficheiro em modo texto. Depois tens que ler linha a linha e colocar o conteúdo da mesma em cada um dos campos da estrutura. O fscanf ajuda muito 🙂 Então mas o facto de a informação estar guardada num ficheiro em modo binário não me obriga a usar o modo de leitura também em binário ('rb')? Btw...não podes dar um exemplozinho de como é que eu leio para uma estructura? É que não sei bem como usar o fread...não sei se leia tudo de uma vez se não. Para ler tudo de uma vez tenho de primeiro verificar quantos elementos tem o ficheiro certo? O mais perto que estive de ler tudo correctamente foi com: for (n=0; n<nt; n++) { fread(&carro, sizeof(carro), 1, fp); //LÊ DADOS printf("\n\nID: %d \n Classe: %d \n Entrada: %d \n SaÃda: %d \n Hora de entrada: %s \n Hora de SaÃda: %s", carro.ID, carro.classe, carro.port_in, carro.port_out, carro.port_in_time, carro.port_out_time); getchar(); } Em que "nt" é o número total de elementos do ficheiro. Mas não sei porque, só lê a 1ª linha correctamente...o resto é lixo. Cumprimentos e mais uma vez muito obrigado por me ajudares e esclareceres as minhas dúvidas 😄 "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
TheDark Posted January 9, 2008 at 01:03 AM Report Share #158790 Posted January 9, 2008 at 01:03 AM Neste caso não usas o fread, usas o fscanf. E é aconselhável abrires o ficheiro em modo não binário. Fazes fscanf(fp, " %d\n%d\n%d", &separador, &carro.ID, &carro.classe); e por aí fora para cada carro. Desaparecido. Link to comment Share on other sites More sharing options...
Carloz Posted January 9, 2008 at 11:35 PM Author Report Share #159012 Posted January 9, 2008 at 11:35 PM Bem...afinal o meu problema estava na declaração da estructura :\. Bastava acrescentar lá uns short's e uns unsigned's e prontos. Está a funcionar na perfeição. Se surgir mais alguma coisa posto aqui 😛 Muito obrigado TheDark. Cumps "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
jfbr Posted January 10, 2008 at 05:24 PM Report Share #159105 Posted January 10, 2008 at 05:24 PM Viva, aproveito a thread para pedir um esclarecimento. Estou a fazer a leitura do ficheiro correctamente. Agora preciso de manipular as strings de tempo entrada e tempo saída, para calcular os tempos de permanência. Qual será o melhor método para retirar os inteiros das strings do tipo xxH xxM xxS ? Tenho estado a tentar com a função atoi, mas não acede correctamente ao que quero. Devo passar a string para um vector e ir la buscar os dados? obrigado Link to comment Share on other sites More sharing options...
TheDark Posted January 11, 2008 at 01:04 AM Report Share #159197 Posted January 11, 2008 at 01:04 AM Com a fscanf não consegues? Desaparecido. Link to comment Share on other sites More sharing options...
jfbr Posted January 11, 2008 at 01:25 AM Report Share #159199 Posted January 11, 2008 at 01:25 AM Com a fscanf não consegues? viva, a sscanf resultou. 😛 Link to comment Share on other sites More sharing options...
Carloz Posted January 15, 2008 at 10:58 PM Author Report Share #160057 Posted January 15, 2008 at 10:58 PM Boas mais uma vez Então é o seguinte... Questão 1: Eu tenho um array de caracteres que representa o meu tempo. Algo deste género: "00h 00m 00s". O que eu preciso é de retirar os valores (inteiros) correspondentes às horas, minutos, e segundos e coloca-los em variaveis. Eu já o fiz e usei duas funções do 'string.h', a 'atoi' (retira os primeiros digitos duma string) e a 'strtok' (divide uma string em várias). Contudo queria saber se há alguma maneira mais correcta/fácil para o fazer. Questão 2: Como é que eu represento um inteiro com dois digitos? Por exemplo em vez de '1horas' escrever '01horas'. Obrigado e cumprimentos "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
TheDark Posted January 16, 2008 at 01:14 AM Report Share #160086 Posted January 16, 2008 at 01:14 AM Contudo queria saber se há alguma maneira mais correcta/fácil para o fazer. sscanf! Se tens por exemplo um array de caracteres assim: char str[]="Sao 10h25m", um sscanf(str, "Sao %dh%dm", &horas, &minutos) faz o que queres. Como é que eu represento um inteiro com dois digitos? Por exemplo em vez de '1horas' escrever '01horas'. http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf("%05d horas", horas); No %05d, o 0 diz para preencher o número com zeros, e o 5 diz para no mínimo escrever o número com 5 algarismos. Desaparecido. Link to comment Share on other sites More sharing options...
Carloz Posted January 16, 2008 at 03:42 PM Author Report Share #160145 Posted January 16, 2008 at 03:42 PM Contudo queria saber se há alguma maneira mais correcta/fácil para o fazer. sscanf! Se tens por exemplo uma string com "Sao 10h25m", um sscanf("Sao %dh%dm", &horas, &minutos) faz o que queres. Como é que eu represento um inteiro com dois digitos? Por exemplo em vez de '1horas' escrever '01horas'. http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf("%05d horas", horas); No %05d, o 0 diz para preencher o número com zeros, e o 5 diz para no mínimo escrever o número com 5 algarismos. Esclarecidíssimo! Só uma questão...como é que eu uso o o sscanf com um variável? É que a minha string está numa array de caracteres. Muito obrigado TheDark (mais uma vez). 😛 Cumprimentos "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
TheDark Posted January 16, 2008 at 04:20 PM Report Share #160156 Posted January 16, 2008 at 04:20 PM Ups. Hehe, enganei-me ali. Com a correcção já deve dar para perceber. Desaparecido. Link to comment Share on other sites More sharing options...
Carloz Posted January 20, 2008 at 02:22 AM Author Report Share #161043 Posted January 20, 2008 at 02:22 AM Só para informar que terminei o programa. Muito obrigado TheDark pela ajuda, paciência, e esclarecimentos. Aqui fica o resultado final 😞 Link Cumprimentos "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
Swimmer Posted January 22, 2008 at 11:21 PM Report Share #161613 Posted January 22, 2008 at 11:21 PM @Buttpt Boas... Eu estou a tentar fazer esse trabalho e deparo-me com um problema... As minhas contas não batem certas, ou seja, quando estou a converter as horas para segundos, o meu tempo médio não bate certo com o tempo médio que o gestaov1 apresenta... Estou a ler as horas, minutos e segundos, converter tudo para segundos, faço as contas entre o final e o inicial e depois faço a média aritmética da conta entre a variação do tempo a dividir pelo numero de carros numa dada classe. Tiveste esse problema? Se sim, como o resolveste? Se não, preciso de ideias 🙂 :) Link to comment Share on other sites More sharing options...
Carloz Posted January 23, 2008 at 12:38 AM Author Report Share #161622 Posted January 23, 2008 at 12:38 AM Isso é em que item? Certifica-te que estás a ler as horas/minutos/segundos da string correctamente. Usa a função sscanf como explicada pelo TheDark, é o método mais simples. Verifica também se o teu algoritmo de conversão para segundos e vice-versa está correcto. Usámos esse algoritmo no 2º ou no 3º trabalho prático. Não percebi muito bem isso da média. Estás a calcular a média do que? Cumps "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
Swimmer Posted January 23, 2008 at 12:47 AM Report Share #161625 Posted January 23, 2008 at 12:47 AM 3ª opção do menu... Estou a ler correctamente os valores e estou a usar sscanf. As conversões para segundos parecem-me correctas mas os meus valores em segundos não coincidem com os valores que o gestaov1 apresenta... Estou a calcular a parte do tempo médio. Ou seja, somo os tempos que cada carro demorou entre 1e3 e depois divido esse tempo total pelo numero de veiculos... Link to comment Share on other sites More sharing options...
Carloz Posted January 23, 2008 at 05:29 PM Author Report Share #161730 Posted January 23, 2008 at 05:29 PM 3ª opção do menu... Estou a ler correctamente os valores e estou a usar sscanf. As conversões para segundos parecem-me correctas mas os meus valores em segundos não coincidem com os valores que o gestaov1 apresenta... Estou a calcular a parte do tempo médio. Ou seja, somo os tempos que cada carro demorou entre 1e3 e depois divido esse tempo total pelo numero de veiculos... Então mas como sabes que os teus valores em segundos não coincidem se o gestaov1 apresenta apenas o resultado final em hora/minuto/segundo? Para esse item, primeiro que tudo, tens de verificar para cada carro, se o seu percurso é a auto-estrada 1-3 ou 3-1. Depois de o verificares, calculas o tempo de permanencia do veiculo, onde terás então te extrair as horas/minutos/segundos para segundos, e fazer a diferença entre o tempo de saida e o tempo de entrada. Depois de o verificares, adicionas o tempo de permanencia calculado ao tempo de permanencia geral para essa classe, e tens também de ter uma variavel que conte os carros dessa classe, logo terás de incrementar 1 à mesma. No final, depois de percorreres os carros todos, fazes a média para cada classe que será o tempo de permanencia total dessa classe a dividir pelo numero de carros da mesma. Por fim, é so pegares na media e voltares a converter para horas/minutos/segundos. Apresentas os resultados e voilá! Cumps "Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV) Link to comment Share on other sites More sharing options...
pedrix21 Posted July 5, 2009 at 01:51 AM Report Share #277061 Posted July 5, 2009 at 01:51 AM Obrigado pela disposição. Mas penso que não seja isso que esteja a procura. Porque para além de ter um vector do tipo Comboios tenho la dentro um vector do tipo STACK (lista ligada) e outra lista ligada. Obrigado mais uma vez 😕 @Pedro Lopes 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