As variáveis que "guardam" arquivos (declaradas como FILE *arquivo) estao dando problema toda vez que preciso passa-las como argumento de função.
Exemplo:
void funcao(FILE *arquivo, char string[])
{
arquivo = fopen (string, "w");
}
int main ()
{
char c;
char string[100];
FILE *arquivo;
scanf ("%s", string);
funcao (arquivo, string);
fprintf (arquivo, "%c", c);
return 0;
}
Nesse exemplo, funciona tudo normal, a função funciona, tudo que está dentro dela acontece normalmente, mas ai quando o programa volta para ler o que acontece depois da função (no caso o fprintf) ele não funciona, ele cria o arquivo (fopen dentro da função) mas na hora do fprintf ele não "printa" nada no arquivo criado (ou seja o arquivo criado fica em branco). É como se o arquivo tivesse sumido aundo voltou da função.
O único jeito que eu encontrei de resolver isso foi deixar tudo que estaria dentro de uma função que recebe arquivos, dentro do main, mas isso me deixa com o problema de que nas funções obrigatórias do EP eu precisaria passar arquivo como argumento.
Como posso resolver esse problema?
Re: Problema ao passar arquivo como argumento de função.
É... eu tive o mesmo problema.
Resolvi ele exatamente como vc disse... eu fecho o arquivo sempre na mesma função que o abriu (seja ela main ou não (não no meu caso hehehe)) passando o arquivo para as funções que se interessam com ele como um argumento.
Talvez o problema seja que arquivo é um ponteiro que ainda não está apontando para lugar nenhum quando voçê chama a função. Estou conseguindo mandar variáveis do tipo FILE entre funções tendo o cuidado de sempre iniciar elas com um fopen antes de mandá-la como argumento.
Acho que não é bem isso que voçê queria, mas de qualquer forma colokei um exemplo que usa uma variavel FILE como argumento
EXEMPLO:
#include <stdio.h>
void EscreveOiNoArquivo(FILE *arquivo)
{
fprintf(arquivo, "OI!");
}
int main ()
{
char string[100];
FILE *arquivo;
scanf ("%s", string);
arquivo=fopen(string, "w"); /*agora que a variavel aponta para o arquivo...*/
EscreveOiNoArquivo(arquivo);/*...posso passá-la como argumento*/
return 0;
}
#include <stdio.h>
void EscreveOiNoArquivo(FILE *arquivo)
{
fprintf(arquivo, "OI!");
}
int main ()
{
char string[100];
FILE *arquivo;
scanf ("%s", string);
arquivo=fopen(string, "w"); /*agora que a variavel aponta para o arquivo...*/
EscreveOiNoArquivo(arquivo);/*...posso passá-la como argumento*/
fprintf(arquivo, "\nTESTE") /* o meu da problema nesse tipo de comando, que vem depois que o arquivo "volta" da função, ele simplesmente não executa o comando */
return 0;
O problema é quando "volta" pro main, ai ele parece que não reconhece mais o arquivo.
Re: Problema ao passar arquivo como argumento de função.
Criem uma função assim:
FILE* abrearquivo (char* nome )
{
FILE* abriu;
abriu = fopen(nome,"w");
return abriu;
}
Fica mais fácil (e não precisa usar ponteiro pra ponteiro (que seria necessário para fazer do jeito q vcs querem))
PS: Aqui eu não tratei, mas tratem os possíveis erros de abertura.
Pelo menos aqui, a alteração que vc fez deu certo e o arquivo ficou com o conteudo:
OI!
TESTE
mas o jeito do rodrigo deve funcionar melhor,,,:D
Re: Problema ao passar arquivo como argumento de função.
arquivo = fopen(string, "w");
a alteração só será válida dentro da função! Esse é o problema com o código que o Caio postou na primeira mensagem desta thread.
Analisando em detalhes... A linha
FILE *arquivo;
declara uma variável tipo ponteiro que não está inicializada. Essa variável serve para apontar para um FILE (seja lá o que isso for), mas (por enquanto) ela não aponta para nada, ou seja, ela contém "lixo", em vez de conter o endereço de algum FILE. Uma variável como essa é geralmente inicializada por uma atribuição
arquivo = fopen(string, "w");
É essa atribuição que coloca na variável arquivo o endereço (devolvido pela chamada a fopen) de um FILE!
Agora vejamos este trecho do programa que o Caio postou:
FILE *arquivo;
scanf("%s", string);
funcao(arquivo, string);
fprintf(arquivo, "%c", c);
Lembrem-se que na passagem de parâmetros o que ocorre é uma cópia dos valores passados como parâmetros. Ou seja, a funcao do Caio recebe uma cópia do lixo contido na variável arquivo. Embora ela atualize essa cópia com o endereço devolvido pela chamada fopen, a atualização só vale dentro da funcao! O endereço é perdido quando a funcao volta para quem a chamou. Quando é executado o fprintf(arquivo, "%c", c), a variável arquivo contém exatamente o mesmo lixo que ela continha antes da chamada à funcao!
A maneira mais fácil de resolver esse problema é a que o Rodrigo indicou. Outra forma (mais complicada, que é bom conhecer mas não vale a pena usar neste caso) é usar um ponteiro para um ponteiro, ou seja passar à funcao o endereço de um ponteiro para que ela possa inicializar o ponteiro:
void funcao(FILE **arq, char string[])
{
*arq = fopen(string, "w");
}
int main()
{
char c;
char string[100];
FILE *arquivo;
scanf("%s", string);
funcao(&arquivo, string);
fprintf(arquivo, "%c", c);
return 0;
}
Agora a declaração do primeiro parâmetro da função (FILE **arq) diz que ele é um ponteiro (o * mais à direita) para um FILE *. Em outras palavras, arq é o endereço de um FILE *, e *arq é um FILE *. A função agora usa esse ponteiro para inicializar o FILE * apontado por ele com o endereço devolvido por fopen. Notem que, na chamada a função, é passado o endereço (&) da variável arquivo, cujo tipo é FILE *.
Como ponteiros para ponteiros são uma coisa mais complicada e difícil de entender, eles só devem ser usados quando realmente houver necessidade. Quando a solução do Rodrigo (devolver o FILE * como valor da função) for aplicável, ela deve ser preferida. Usem ponteiros para ponteiros apenas quando essa solução não for aplicável: caso vocês precisem de uma função que devolva mais de um ponteiro (um FILE *f1 e um FILE *f1, por exemplo -- só um deles pode ser devolvido como valor da função, o outro terá que ser devolvido através de um argumento como FILE **endereco_de_FILE_ptr).