Duvidas em implementar funções em C

Psycop

I fold therefore I AM
Boas

Estou a aprender a programar em C e tenho tido algumas dúvidas com subprogramas, e ainda não percebi muito bem toda a sua mecânica. Estava a tentar implementar um função para ler um ficheiro em C, mas não estou a conseguir.

O código que criei até agora foi:

Código:
#include <stdio.h>#include <stdlib.h>


#define N 1000


void ler_ficheiro(int *num_linhas, int *ano[N], int *mes[N], int *dia[N], int *hora[N], int *min[N], int *seg[N], float *temperatura[N])
{
    FILE *entrada;
    int i;


    entrada = fopen("log.txt", "r");


    if (entrada == NULL)
    {
        printf("Erro na Abertura do Ficheiro de Entrada:\n\n");
        system("PAUSE");
    }
    else
    {
        while (!feof(entrada))
        {
            fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
            printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);


            num_linhas = num_linhas + 1;


            i++;
        }


        printf("\n\n");
        printf("Numero de Linhas = %d\n\n", num_linhas);


    }




}


int main()
{
    ler_ficheiro(int *num_linhas, int *ano[N], int *mes[N], int *dia[N], int *hora[N], int *min[N], int *seg[N], float *temperatura[N]);
}

Alguém me consegue explicar no que estou a falhar e o porquê?

Cumps
 
Boas,
tu fazes

void ler_ficheiro(int *num_linhas, int *ano[N], int *mes[N], int *dia[N], int *hora[N], int *min[N], int *seg[N], float *temperatura[N])

o primeiro argumento é uma apontador para um inteiro,
quanto aos restantes argumentos se a tua ideia é passar vectores como argumentos não é assim que se faz.
Para passares vectores como parametros podes fazer como no programa em baixo. Vê como eu faço nas duas funçoes tanto na chamada como na declaração das funçoes.

#include<stdio.h>
#define n 10
void tes(int *v);
void imp(int v[]);


void tes(int *v){
int i;
for (i=0;i<n;i++){
v=i;
}
imp(v);
}
void imp(int v[]){
int i;
for(i=0;i<n;i++){
printf("vec[%d]=[%d]\n",i,v);
}
}
main(){
int vec[n];
tes(vec);
}

Cumps
 
Diz-me uma coisa, vais passar alguns parametros para a função ler_ficheiro? (eu acho que não)
Se sim, no main, quando chamas a função passas os valores ( sem declaração do tipo ).
Caso contrário, passas a função para ler_ficheiro() (apenas, sem os argumentos), declaras as variaveis que precisas dentro da função. No Main, chamas apenas a função ler_ficheiro().

Fiz-me entender ?

Cptos
 
Boas

Não quero passar nenhum argumento, apenas quero carrregar os dados para o array e retornar o num_linhas para fora da função para posteriormente poder usar no calculo de estatisticas.

Cumps
 
Se estás a usar fscanf tens de ter a certeza que o que está no ficheiro está mesmo nesse formato. Por exemplo, aquele "A temperatura é" tem de estar exactamente igual. Já para não falar que acentos em C nao funcionam assim às três pancadas...

Certifica-te que crias-te as variáveis que estás a lançar para a função.
O teu main devia estar assim:
Código:
int main()
{
   int num_linhas[N], ano[N], mes[N], dia[N], hora[N], min[N], seg[N];
   float temperatura[N];
ler_ficheiro(&num_linhas, &ano, &mes, &dia, &hora, &min, &seg, &temperatura); // só tens de passar estas variáveis por referência (ou seja a sua posição de memória) se quiseres que o seu conteúdo seja alterado pela função.
  return 0;
}


Se o que queres é ler uma linha do ficheiro e imprimi-la, tens uma função chamada getline(&buffer, size_t* n, FILE* f). O que isto faz é ler uma linha do ficheiro apontado por f e colocar no buffer. Depois é só fazer printf do buffer.

Exemplo:
Código:
char* linha = (char*)malloc(30*sizeof(char));
size_t* n = (size_t*)malloc(sizeof(size_t));
FILE* acc = fopen(accounts, "r");
getline(&linha, n, acc);
Isto cria um array (buffer) de 30 caracteres, cria um size_t* genérico e abre um ficheiro accounts.txt (definido num define qlq) e lê a linha do ficheiro para o buffer linha.

Depois manipulo o array como quero com o strtok.
 
Última edição:
Boa Tarde

Estou novamente com problemas na criação da função para ler os dados de um ficheiro.

O código que criei até agora é o seguinte:

Código:
#include <stdio.h>
#include <stdlib.h>


#define N 1000


void ler_ficheiro(int *num_linhas, int *ano, int *mes, int *dia, int *hora, int *min, int *seg, float *temperatura)
{
    FILE *entrada;
    int i = 0;


    entrada = fopen("log.txt", "r");


    if (entrada == NULL)
    {
        printf("Erro na Abertura do Ficheiro de Entrada:\n\n");
        system("PAUSE");
    }
    else
    {
        while (!feof(entrada))
        {
            fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
            printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);


            num_linhas = num_linhas + 1;


            i++;
        }


        printf("\n\n");
        printf("Numero de Linhas = %d\n\n", num_linhas);


    }




}


int main()
{
    int i = 0;


    int dia[N], mes[N], ano[N], hora[N], min[N], seg[N];
    float temperatura[N];


    ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);
}

Os erros de compilação são os seguintes:

tica\LM335A\V_1.03\main.c||In function 'main':|
tica\LM335A\V_1.03\main.c|39|warning: passing argument 7 of 'ler_ficheiro' from incompatible pointer type|
tica\LM335A\V_1.03\main.c|5|note: expected 'int *' but argument is of type 'float *'|
tica\LM335A\V_1.03\main.c|39|error: too few arguments to function 'ler_ficheiro'|
||=== Build finished: 1 errors, 1 warnings ===|

Alguém me poderia explicar onde é que estou a errar e porquê?

Cumps
 
Última edição:
Esses erros são bastante fáceis de perceber.

Os erros estão todos na função main.

A função ler_ficheiro recebe 8 argumentos e estás a passar apenas 7, não estás a passar o número de linhas. E atenção que a ordem pela qual estás a passar os argumentos não é a mesma ordem que está no cabeçalho da função pelo que poderás ter resultados que não estás à espera. Experimenta resolver estes problemas e experimenta correr
 
Boas

Realmente não estava mesmo a dar conta que tinha o num_linhas!

Sabendo que necessito do num_linhas para o calculo das estatísticas dos valores como poderei saber o num de linhas e retornar o valor da função?

para calcular o num de linhas bastaria:
Código:
while (!feof(entrada))        {
            fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
            printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);




            num_linhas = num_linhas + 1;




            i++;
        }

Mas depois deparo-me com problemas ao retornar este valor para fora da função.

Cumps
 
Retornar um valor é fácil.

Basta declarares a função como int, porque queres devolver o número de linhas que é inteiro, e no final da função fazes return número de linhas. Mas atenção que isso não vai resolver o teu problema. Tu tens que saber o número de linhas antes de chamar a função ler_ficheiro, porque ao chamares essa função precisas de dar o número de linhas como argumento
 
Então a solução seria criar uma função antes da função ler_ficheiro() que efectuasse a contagem do num_linhas?

Cumps
 
Se precisas mesmo que a função tenha esse argumento, então sim. Mas isso é facil de contar, é só ler até encontrar o EOF.
 
O post é grande, mas acho que vale a pena para o autor do tópico.

Vamos só recapitular aquilo que até agora já aprendeste neste tópico:
Aprendeste que uma função é "declarada"/"criada" seguindo o seguinte formato:

[tipo de retorno] [nome da função](arg1, arg2, ...){

/* Código */

}

Por exemplo:
Código:
void imprime_inteiro(int inteiro_a_imprimir){
   printf("%d\n", inteiro_a_imprimir);
}
É void porque não retorna nada para o main, e recebe apenas o argumento, do tipo int.

No main(), a função é chamada simplesmente através do seu nome e com a passagem dos argumentos, exemplo:

Código:
int main(){
   
   imprime_inteiro(5);

/* OU int valor = 5; imprime_inteiro(valor);  - como quiseres */
}

OK, vamos avançar.

Tens ainda duas versões da tua função:

Opção 1:

Código:
void ler_ficheiro(int *num_linhas, int *ano[N], int *mes[N], int *dia[N], int *hora[N], int *min[N], int *seg[N], float *temperatura[N])

Opção 2:

Código:
void ler_ficheiro(int *num_linhas, int *ano, int *mes, int *dia, int *hora, int *min, int *seg, float *temperatura)

Vamos desenvolver um pouco estas opções. Repara que qualquer uma delas funciona para aquilo que queres. Porquê?

Normalmente numa função, o valor dos argumentos que são passados lá para dentro são valores que só são válidos no contexto da função, ou seja, se tu passares um inteiro por valor para dentro duma função e alterares o valor desse inteiro na função, isso é válido dentro da função, mas essa alteração não se "propaga" para o main.
Daí no scanf() (por exemplo), teres de passar os inteiros/floats/caracteres por referência (&inteiro), porque o scanf quer alterar o valor dessas variáveis. Tu ao passares a variável por referências estás a enviar não o valor da variável mas sim a posição de memória onde essa variável se encontra. A única coisa que o scanf (ou qualquer outra função que altere valores) tem de fazer é aceder à posição APONTADA pelo ponteiro que é recebido (ao passares por referência, estás a enviar a posição de memória, ou seja, é um ponteiro) e simplesmente alterar. Repara que o valor do ponteiro nunca é alterado, mas o valor da posição APONTADA por esse ponteiro é que é alterado. De qualquer forma, essa alteração é feita na função e mantém-se feita no main() porque tu não alteraste o valor/ponteiro que enviaste para dentro da função, tu alteraste foi o valor apontado por esse ponteiro, e isso é completamente diferente.

Agora fazemos aqui um sleep(20); para que possas processar aquilo que acabei de dizer...

Pronto, então compreendes que a tua primeira opção funciona, e de acordo com aquilo que eu disse até é a mais correcta, porque estás a receber ponteiros para os vectores de inteiros que queres alterar. Depois na tua função só tens é que ter cuidado para alterares os valores apontados por esses ponteiros e não os próprios ponteiros.
Então, mas assim sendo, porque motivo é que a tua Opção 2 também funciona? Porque em C, a variável que define um vector pode ser tratado como um ponteiro.
Quanto tu declaras int vector[10], estás a reservar espaço em memória para um vector de 10 inteiros, e a variável vector é um ponteiro que aponta para a primeira posição de memória desse vector. Ou seja *vector ou vector[0] é exactamente a mesma coisa. O que é que isso significa? Significa que quando se enviam vectores para dentro de função, muito provavelmente não será necessário passá-los por referência porque, normalmente, aquilo que se altera é os valores apontados pelo vector (que na prática é um ponteiro), logo podes passar directamente como valor.
Podes testar em casa que:
*vector == vector[0];
*vector + 1 == vector[1];
*vector + 2 == vector[2];
etc

Quando usas a expressão vector, o computador automaticamente sabe que estás a aceder ao valor que está armazenado na i-ésima posição de memória a contar da "base" do vector (ou melhor dito, contado a partir do vector[0]).
Conclusão, a tua segunda Opção também é correcta porque na função estás a receber um vector como se fosse um ponteiro (e na prática é) e nunca alteras o ponteiro, mas sim os valores presentes na memória que para a qual esse ponteiro aponta (directa ou indirectamente). Volto a repetir que fazeres vector[2] é o mesmo que dizeres que queres aceder à posição de memória apontada por vector + 2 posições de memória.

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


Repara apenas que eu estive aqui a falar de vectores e as suas características "especiais" que permitem que seja tratado como um ponteiro, mas se estivemos a falar de apenas inteiros, floats ou caracteres normais, esses têm mesmo de ser passados por referência. Repara que no scanf(), sempre que queres um inteiro, float ou caracter tens sempre de o passar por referência, no entanto o mesmo não se passa com strings, porque uma string é um vector de caracteres (com um caracter terminador '\0' no fim) e logo pode ser tratado como ponteiro.


OK. fazemos mais um sleep(60); para pensares nisto que eu disse, e continuamos:

Pelo que percebi, tu queres retornar o número de linhas.
A tua função tem um ciclo que lê até ao EOF, indo contando as linhas do ficheiro.
Tens duas opções para isto, e uma delas é enviar um ponteiro para um inteiro num_linhas lá para dentro (que foi o que fizeste) e no final armazenas a contagem de linhas na posição de memória apontada por esse ponteiro:

Código:
/* Não esquecer de inicializar o num_linhas */
*num_linhas = 0;

 while (!feof(entrada))
        {
            fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
            printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);

/*--------------------------AQUI--------------------*/

           [B] *num_linhas = *num_linhas + 1;[/B]
/*---------------------------------------------------*/

            i++;
        }

Tu tinhas num_linhas = num_linhas + 1;, mas isso não estava a incrementar o valor do numero de linhas mas sim o ponteiro. Na prática não tavas a fazer aquilo que queres.
Assim, como eu pus, tu estás a somar mais um ao valor apontado pelo ponteiro num_linhas, que é aquilo que queres*/

Não te eskeças que no main tens de declarar int num_linhas e depois passá-lo para dentro da função por referência (&num_linhas). A função trata de armazenar lá a quantidade de linhas e depois no main ficas com o valor correcto no num_linhas.

----------

Entretanto, tens outra forma de fazer isso, que é a forma mais "normal".
Invés de passares o num_linhas por referência no main, e estares a alterar o valor apontado na função, podes simplesmente mudar o cabeçalho da função, de forma a não receber o int * num_linhas, e a receber apenas os 7 argumentos principais. No final da função, simplesmente retornas o número de linhas para o main(). Como fazes isso? Para já a função invés de ser void é int, e depois tens de fazer o "return" correcto:

Código:
int ler_ficheiro(int *ano, int *mes, int *dia, int *hora, int *min, int *seg, float *temperatura){

/*Codigo*/

return i; /* (penso que a tua contagem de linhas era a variável i */

}

E no main fazes:

Código:
int main()
{
    int i = 0; /* ISTO NÃO ESTÁ AQUI A FAZER NADA, DEVES APAGAR ISTO DAQUI */


    int dia[N], mes[N], ano[N], hora[N], min[N], seg[N];
    float temperatura[N];

/*------------------AQUI-------------------*/

    int num_linhas;
    num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);

/*------------------------------------------*/


}

Penso que por agora é tudo.

Cumps
 
Última edição:
Boa Noite

Obrigado por este esclarecimento mais profundo, está a ser muito útil para entender bem o conceito.

Efectuei as alterações no código que sugeriste, e o que acontece é que é compilado sem problemas e sem erros, mas na execução é lida a primeira linha do ficheiro, mas depois a aplicação deixa de responder!

O código é o seguinte:

Código:
#include <stdio.h>#include <stdlib.h>


#define N 1000




int ler_ficheiro(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
        FILE *entrada;
        int i = 0;
        int *num_linhas;


        entrada = fopen("log.txt", "r");
        if (entrada == NULL)
        {
                printf("Erro na Abertura do Ficheiro de Entrada:\n\n");
                system("PAUSE");
        }
        else
        {
                while (!feof(entrada))
                {
                        fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
                        printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);


                        *num_linhas = *num_linhas + 1;


                        i++;
                }


                return *num_linhas;
        }


}




int main()
{
        int dia[N], mes[N], ano[N], hora[N], min[N], seg[N];
        float temperatura[N];
        int num_linhas;


        num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);
}

Esta situação de deixar de responder prende-se com a má implementação de algo?
 
Começar por dizer que o teu main() está correcto.

Ponto 1: Tu na função declaras int *num_linhas;, mas isso não é necessário. Estás dentro da função, a variável num_linhas vai existir apenas dentro da função (a do main() apesar de ter o mesmo nome, é uma variável completamente diferente), logo podes simplesmente declará-la como inteiro normal... int num_linhas.
Repara no entanto que nem era preciso, bastava fazeres return i; (eu entretanto modifiquei o meu post anterior para adicionar isto e adicionei mais uns detalhes, se tiveres tempo dá mais uma olhadela). No entanto, se queres mesmo ter uma variável explícita num_linhas, então declara-a normalmente como inteiro, mas não é necessário porque o i já é um contador....

Onde está o problema? Vamos lá dar mais um bocadinho de teoria relaccionada com ponteiros... (e isto é suposto ser o Ponto 2):

Em todos os casos que tivemos a discutir no post anterior, tu declaravas no main a variável de forma normal, e depois passavas por referência (ou no caso dos vectores eles já eram equivalente a ponteiros, logo passava-se normalmente). Isto funciona porque, como já os declaraste todos no main, a memória para essas variáveis já foi reservada, e quando passas por referência, obténs um ponteiro para uma posição de memória válida.

NO ENTANTO, quando declaras mesmo, de forma explícita, um ponteiro (por exemplo, int * num_linhas), esse ponteiro inicialmente não aponta para lado nenhum ou, eventualmente, pode apontar para posições de memória inválidas (inválidas = não fazem parte da memória do nosso programa).
Por exemplo, se fizeres int valor;, inicialmente não sabes o que é que está armazenado na variável valor. Pode ser 0 mas também pode ser lixo, por isso é que normalmente se inicializa, e o mesmo se passa na declaração de um ponteiro: inicialmente, esse ponteiro pode apontar para posições de memória que nem existem ou são inválidas...

Tu no teu código, após declarares o ponteiro, estás a querer aceder a essa posição de memória (que é lixo) e a querer alterá-la, e nesse caso o Windows/Linux matam-te o programa, porque não estás autorizado a aceder à posição de memória que potencialmente estavas a tentar aceder.

Tens apenas duas opções para resolver esse problema. Ou fazes como eu sugeri no Ponto 1, que é o normal, ou então fazes uma coisa que se calhar já é demasiado avançado para o teu nível actual: reservas memória para esse ponteiro, com a chamada da função malloc().

O malloc é uma chamada do sistema que pede ao Sistema Operativo que lhe reserve um espaço de memória do tamanho que a gente indicar. O malloc() retorna um ponteiro para essa posição de memória, logo pode-se fazer o seguinte:

Código:
int * num_linhas = (int*) malloc(sizeof(int));

malloc(sizeof(int)) pede ao SO para reservar um espaço de memória do tamanho de um inteiro. Depois o malloc retorna um ponteiro para essa posição de memória, que fica guardado no ponteiro num_linhas. A partir de agora, sempre que usares *num_linhas, já estás a aceder a uma posição de memória que faz parte do teu programa, e o programa já não vai crashar.


---CURIOSIDADE---

o (int*) que está antes do malloc() chama-se um "cast". Acontece que o malloc() é uma função que pode reservar memória de qualquer tipo: inteiros, floats, caracteres, ou qualquer outro tipo de variável possível. Daí, o malloc() retorna um ponteiro "abstracto"... O cast só está ali para que o compilador interprete o ponteiro retornado pelo malloc() como um ponteiro para inteiro. Pode nem ser preciso usar o cast, mas alguns compiladores reclamam.

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

Desvantagens do malloc: Enquanto que ao fazeres int num_linhas, é o programa que automaticamente reserva a memória necessária e, no fim, a liberta, ao declarares um ponteiro int *num_linhas e usar o malloc() de forma explícita, tens de ser também tu, no final da função, a libertar a memória que reservaste por tua própria iniciativa, através da função free();

Código:
int *num_linhas = malloc(sizeof(int)); /* Repara que omiti o cast de propósito porque normalmente não costuma ser relevante*/

/*codigo*/

free(num_linhas);

return i;


O meu conselho: Usa a Ponto 1. O malloc() usa-se em determinadas situações, que deves estar prestes a aprender, onde tem de ser o próprio programador a reservar a memória necessária de forma explícita, quer seja porque só a meio do programa é que sabe a quantidade de memória que vai necessitar (e repara que as declarações são feitas no início do código), ou porque em certas situações e mais útil usar ponteiros, etc etc... Qualquer que seja o caso, são um pouco mais acima do teu nível (não muito mais), pelo que assumo que ainda não aprendeste e portanto não te deves estar a importunar com isto agora. Usa a minha sugestão do Ponto 1.

Cumps
 
Última edição:
Boa noite mais uma vez!

Agradeço por todas estas explicações. O que é certo é que eu já dei toda essa matéria na cadeira de programação, mas nunca fiquei muito à vontade com funções, por esse mesmo facto que estou agora a tentar batalhar um pouco nisso de modo a interiorizar bem os conceitos pois penso que vão ser muito úteis no futuro.

Usei o livro de C do Luis Damas, mas confesso que o capítulo da passagem de parâmetros e funções deixa um pouco a desejar, pelo menos para mim.a

Quanto a esta ultima explicação ajudou mais um pouco, mas ainda assim vou voltar a ler tudo novamente para interiorizar tudo, entretanto implementei o que sugeriste e já funciona correctamente...

O código é o seguinte:

Código:
#include <stdio.h>#include <stdlib.h>


#define N 1000




int ler_ficheiro(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
        FILE *entrada;
        int i = 0;


        entrada = fopen("log.txt", "r");
        if (entrada == NULL)
        {
                printf("Erro na Abertura do Ficheiro de Entrada:\n\n");
                system("PAUSE");
        }
        else
        {
                while (!feof(entrada))
                {
                        fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
                        printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);


                        i++;
                }


                return i;
        }


}




int main()
{
        int dia[N], mes[N], ano[N], hora[N], min[N], seg[N];
        float temperatura[N];
        int num_linhas;


        num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);
}

No entanto deixa-me dizer-te que esta função que estou a tentar desenvolver vem no seguimento de um projecto pessoal usando o micro-controlador Arduino, o qual eu gosto bastante e poderá ajudar-me a evoluir e consolidar conhecimentos.

Poderás conhecer um pouco mais desse projecto no meu blog pessoal aqui: http://omundodaprogramacao.com/categoria/projectos/

Na pequena aplicação que estou a tentar construir eu já tinha alguns progressos, mas achei por bem implementar todas as funções usando funções ao invés de usar código corrido no main().

Mais uma vez obrigado pelas explicações!

Cumprimentos
Nuno
 
Última edição:
Já funciona? Mas está igual ao outro :eek:
Supostamente não devia funcionar porcausa da questão do
Código:
int *num_linhas;

*num_linhas = *num_linhas + 1;

num_linhas é uma posição de memória inválida, porque não foi inicilializado...

Será que não te enganaste no copy-paste? :p

Cumps
 
Obrigado pelo reparo!

Sim, enganei-me no copy-paste, mas já editei no post anterior para a forma correcta!

Após todas as tuas ajudas e correcções o código final para a minha mini aplicação é:

Código:
#include <stdio.h>#include <stdlib.h>


#define N 1000




int ler_ficheiro(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
        FILE *entrada;
        int i = 0;
        int num_linhas = 0;


        entrada = fopen("log.txt", "r");
        if (entrada == NULL)
        {
                printf("Erro na Abertura do Ficheiro de Entrada:\n\n");
                system("PAUSE");
        }
        else
        {
                while (!feof(entrada))
                {
                        fscanf(entrada, "%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", &dia[i], &mes[i], &ano[i], &hora[i], &min[i], &seg[i], &temperatura[i]);
                        printf("%d-%d-%d %d:%d:%d A Temperatura é de: %f\n", dia[i], mes[i], ano[i], hora[i], min[i], seg[i], temperatura[i]);


                        i++;
                }


                return i;
        }


}


int media_temp(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
    float soma_temp = 0, temp_media = 0;
    int j, num_linhas = 0;


    num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);


    for(j = 0; j < num_linhas; j++)
    {
        soma_temp = soma_temp + temperatura[j];
        temp_media = soma_temp / num_linhas;
    }


    printf("Media = %f", temp_media);
}


float temp_max(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
    float temp_max = 0;
    int j, num_linhas = 0;


    num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);


    for(j = 0; j < num_linhas; j++)
    {
        if (temperatura[j] > temp_max)
        {
            temp_max = temperatura[j];
        }
    }


    printf("Temperatura Maxima = %f", temp_max);
}


float temp_min(int *dia, int *mes, int *ano, int *hora, int *min, int *seg, float *temperatura)
{
    float temp_min;
    int j,num_linhas = 0;


    num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);


    for(j = 0; j < num_linhas; j++)
    {
        temp_min = temperatura[0];


        if (temperatura[j] < temp_min)
        {
            temp_min = temperatura[j];
        }
    }


    printf("Temperatura Maxima = %f", temp_min);
}




int main()
{
        int dia[N], mes[N], ano[N], hora[N], min[N], seg[N];
        float temperatura[N];
        int num_linhas;
        int escolha;


        do
        {
            printf("\t\t\t\t***MENU***");
            printf("\n\n");
            printf("1 - Ler Ficheiro de Dados:\n");
            printf("2 - Calcular a Média das Temperaturas:\n");
            printf("3 - Verificar Temperatura Maxima:\n");
            printf("4 - Verificar Temperatura Minima:\n");
            printf("5 - SAIR\n");
            printf("\n");
            printf("Opcao:");
            scanf("%d", &escolha);


            switch(escolha)
            {
                case 1:
                {
                    printf("\n\n1- Escolheu Ler o Ficheiro de Dados:\n\n");


                    ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);


                    num_linhas = ler_ficheiro(dia, mes, ano, hora, min, seg, temperatura);


                    printf("Num Linhas = %d", num_linhas);
                    printf("\n\n\n");


                    break;
                }


                case 2:
                {
                    printf("\n\n2 - Escolheu Calcular a Media das Temperaturas:\n\n");


                    media_temp(dia, mes, ano, hora, min, seg, temperatura);


                    break;
                }


                case 3:
                {
                    printf("\n\n3 - Verificar Temperatura Maxima:\n\n");


                    temp_max(dia, mes, ano, hora, min, seg, temperatura);


                    break;
                }


                case 4:
                {
                    printf("\n\n3 - Verificar Temperatura Minima:\n\n");


                    temp_min(dia, mes, ano, hora, min, seg, temperatura);


                    break;
                }


                case 5:
                {
                    printf("Escolheu SAIR:");


                    exit(0);
                }


                default:
                {
                    printf("\n\n Opção Errada:");


                    return main();
                }


            }
        }while(escolha != 5);
}

Cumps
 
Última edição:
Back
Topo