Ir ao conteúdo
  • Cadastre-se
Rodney Fernandes

Modularização em uma Manipulação de arquivos em C

Recommended Posts

Estou tendo vários problemas com um código que estou desenvolvendo, pois mesmo tendo um conhecimento mediano em modularização, não havia visto modularização juntamente com manipulação de arquivos e por isso estou tendo vários erros como "too many arguments to function 'FILE* escrever_arquivo(). alguém pode me ajudar? já modifiquei o código bastante e nada. tem coisa que eu não arrumei mas quem puder analisar os erros que eu cometi ficarei grato. 

 

Código :

 

#include<stdio.h>
#include<stdlib.h>

FILE* escrever_arquivo(){
    FILE *Alunos;

    char nome[40];
{
                Alunos = fopen("Alunos.txt", "a");
                printf("Digite o nome de um aluno: ");
                scanf("%s",nome);
                fprintf(Alunos, nome);
                fprintf(Alunos, "\n");
                fclose(Alunos);
                system("pause");
return Alunos;
}
}
FILE* lerarquivo(char *ler){
 int x;
    char nomes [1000];
    char *conseguiuLer;
    char linha[100];
            FILE *Alunos;
                        Alunos = fopen("Alunos.txt", "r");
                        if(Alunos == NULL){
                            printf("Arquivo nao encontrado.\n");
                            system("pause");
                            return 0;
                                          }
                            while (!feof(Alunos))
                            {
                              conseguiuLer = fgets(linha, 100, Alunos)  ;
                              if (conseguiuLer){
                                printf("%s",linha);
                             }                  }
                            fclose(Alunos);

return Alunos;
}
FILE* Fechar_arquivo(FILE *Alunos) {
                            Alunos = fopen("Alunos.txt", "a");
                        if(Alunos == NULL){
                            printf("Arquivo nao encontrado");
                            getchar();
                            }
return Alunos;
}
FILE* valor_invalido(FILE *Alunos) {
                                       printf("opção invalida\n");
                                            fclose(Alunos);
{
return 0;
}
}

int main(void) {
int x;
    FILE *Alunos;
int escreve,ler;
     int caractere, i;
  int quant_linhas = 0;
  char *palavra;
    do {
        system("cls");
        printf("***********************************************************************************************************************\nAlunos: Paulo Henrique Bonifacio Souza e Rodney Fernandes\nCurso de Engenharia da Computa\207\306o\nDisciplina: Linguagens e t\602cnicas de programa\207\306o\nProfessora: Luciene\n");
        printf("***********************************************************************************************************************\n");
        printf("\nEscolha uma opcao:\n\n");
        printf("1-Escrever em um arquivo\n2-Ler um arquivo\n3-Modificar um arquivo\n4-Sair\nDigite a opcao desejada: ");
        scanf("%i", &x);
        if (x==1){
          escreve = escrever_arquivo("Alunos.txt", "a");
          printf(escreve,"Alunos");
                 }
        else {
            if (x==2){
                 ler = lerarquivo("Alunos.txt", "r");
                printf*("lendo",ler);
                     }
             }
          Fechar_arquivo(Alunos);
    }
              }
>

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

você declarou a função que faz a leitura do arquivo tal como "FILE* lerarquivo ( char *ler )", e depois você tenta invoca-la tal como "lerarquivo ( "Alunos.txt", "r" )". Sua função só tem 1 parâmetro, e você está passando "erro: muitos argumentos para a função 'lerarquivo'".

 

Seu código está incompleto assim que não da para sacar muitas conclusões.
Antes de postar uma nova pergunta, em praticamente em todos os fóruns existem regras, procure ler as regras antes de postar um tema, agora mesmo você está passando essa por alto: https://www.clubedohardware.com.br/forums/topic/1136701-botão-code-como-e-para-que-usar/

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp obrigado, alterei o post. porém o erro não se da apenas nesse parâmetro, e sim nos demais que não consegui ajeitar o código na modularização. você poderia digitar o código de como ficaria se possível? estou meio leigo nessa parte de parâmetros junto com a manipulação e estou meio perdido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp é que normalmente o código funciona perfeitamente. apenas na modularização que ***** tudo e precisaria de  pelo menos um exemplo de como eu poderia fazer a modularização onde você tem um meno de opções, usando um variável inteira X, você seleciona a opção desejada e quando fizer isso você verifica qual opção escolheu e vai para a função modularizada e retorna o valor na função principal(até ai tudo bem mas para manipulação de arquivos não está funcionando dessa forma). normalmente sem a modularização tudo funcionou porém gostaria de modularizar o código, e com verificações juntamente com manipulação de arquivos eu estou me confundindo e não sei o que chamar de parâmetro corretamente ou fazer o programa sem erros dessa forma.

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <stdbool.h>
#include <windows.h>

typedef struct Agenda{
	char nome[50]; 
	int telefoneFixo; 
	int telefoneCelular; 
	char email[100];	
}Agenda; 

Agenda agenda={0};

//Prototipos 
//funções modularizadas
int  menu(int opc);
void tomarDadosContato   ( Agenda* contato );
int  lerDadosArquivo     ( FILE* arquivo, Agenda* contato );
void imprimirContato     ( Agenda* contato );
void guardarDadosArquivo ( FILE* arquivo, Agenda* contato );
void pausa();
void limparTela();
void copiar( Agenda* A, Agenda* B );

//Funcionalidades principais do programa(menu).
void incluir  ();
void listar   ();
void organizar();
void excluir  ();

int main (){
    //ajusta o console a 70 letras e 50 linhas
    system("MODE CON cols=70 lines=50");
    
    //Permite letras como ç, ã, á etc
    setlocale(LC_ALL, "portuguese-brasilian");

    bool sair = false;
    int opc = 0;
    while( !sair ){
    	switch ( menu(opc) ) {
		    case 1: incluir  ();   break;
		    case 2: listar   ();   break;
		    case 3: organizar();   break;
		    case 4: excluir  ();   break;
		    case 0: sair = true; break;             
		    default: printf( "Não existe essa opcao\n" ); pausa(); break;
		}//FIN SWITCH
		
    }//FIN WHILE
    
    return 0;
}//FIN MAIN

//Implementação funções do menú
void incluir(){//Função que inclui um contato novo al final do arquivo agenda.txt
    
    
    limparTela();
    FILE* arquivo = fopen( "agenda.txt", "a" );
    if ( arquivo == NULL ){
    	printf ("Nao foi posivel abrir o arquivo incluir o contato.\n");
    	return;
    }
    
	Agenda contato   = {0};
	tomarDadosContato  ( &contato );
    guardarDadosArquivo( arquivo, &contato );
    printf("Contato guardado corretamente. ");
    pausa();
    fclose(arquivo);
    return;
}                
void listar (){//Função que imprime todos os contatos de agenda.txt na tela.
    
    
    limparTela();
    //preparamos um arquivo de leitura.
    FILE* arquivo = fopen( "agenda.txt", "r" );
    if ( arquivo == NULL ){
    	printf ("Nao foi posivel abrir o arquivo para listar os contatos.\n");
    	return;
    }

	Agenda contato;
	rewind(arquivo);
	//Lemos um a um e mostramos na tela.
	while ( lerDadosArquivo( arquivo, &contato ) != EOF ){ //A funçao leerDadosArquivo le um usuario por vez, e se chega no fim do arquivo retorna EOF(fim do arquivo.).
        //Evitamos listar contatos excluidos.
        if ( contato.nome[0] != '*' ){
            imprimirContato( &contato );
        }
    }
	pausa();
	fclose(arquivo);
    return;
}
void organizar(){//Função que organiza em ordem alfabetica o arquivo, e elimina excluidos otimisando assim o arquivo.
	limparTela();
    //Abrimos um arquivo para modo leitura.
    FILE* arquivo = fopen( "agenda.txt", "r" );
    if ( arquivo == NULL ){
        printf("Não foi possivel abrir o arquivo para contar usuarios. ");
        pausa();
        limparTela();
        return;
    }
    
    //Contamos quantos usuarios tem no arquivo... excluindo os que estão marcados de esta forma(excluidos): "**** **** **** *****"
    Agenda contato;
    int contador = 0;
    while ( lerDadosArquivo( arquivo, &contato ) != EOF ){
        if ( contato.nome[0] != '*' ){
            contador++;
        }
    }
    
    //Informamos quantos contatos existem no arquivo excluindo todos os marcados com '*'.
    printf("Encontrados %d contatos validos. ", contador);
	pausa();
    
    //Reservamos memoria dinamica para carregar contatos validos(excluindo os marcados) na free storage(heap).
    Agenda* lista = ( Agenda * )calloc( contador, sizeof( Agenda ) ); //calloc reserva memoria e tambem formata toda ela com nulos.
    
    //voltamos ao principio do arquivo e o carregamos na memoria(lista)
    rewind(arquivo);
    int indice = 0;
    while ( lerDadosArquivo(arquivo, &contato) != EOF ){
        if ( contato.nome[0]!= '*' ){ //Somente copiamos contatos sem excluir(todos os contatos que não sejam *** ***...)
            copiar( &contato, &lista[indice]); 
            indice++;
            if ( indice > contador ){
                indice = contador; //Isso evita que nos ultrapassamos o range maximo.
            }
        }
    }
    fclose(arquivo);
    
    //Imprime contatos sem organizar
    printf ("Sem organizar:\n\n");
    for( int i = 0; i< contador; i++){
        imprimirContato( &lista[i] );
    }

    //Organiza lista de contatos por ordem alfabetica
    for ( int i = 0; i < contador; i++ ){
        for ( int j = 0; j < contador; j++ ) {
            if ( i != j ){
                if ( strcmp ( lista[i].nome, lista[j].nome ) < 0 ) {
                    copiar(&lista[i], &contato);
                    copiar( &lista[j], &lista[i] );
                    copiar( &contato, &lista[j]);
                }
            }
        }
    }    
    
    //Mostra lista organizada por ordem alfabetica
    printf ("Organizados:\n\n");
    for( int i = 0; i< contador; i++){
        imprimirContato( &lista[i] );
    }
    
    //Procedemos a guardar em um novo arquivo, criamos o ponteiro.
    FILE* novoArquivo = fopen("agenda.txt", "w"); //Essa vez o modo é destrutivo, borrará todo o conteudo que estiver no arquivo.
    if ( novoArquivo == NULL ){
        printf("Não foi possivel abrir o arquivo para guardar os dados organizados. ");
        pausa();
        limparTela();
        return; 
    }
    
    //Guardando a lista organizada no arquivo.
    indice = 0;
    while ( indice < contador ){
        guardarDadosArquivo( novoArquivo, &lista[indice]);
        indice++;
    }
    
    //liberando recursos
    free(lista);          //memoria dinamica deve ser liberada antes de sair
    fclose(novoArquivo); //fechamos o novo arquivo
    
    //Avisamos que tudo terminou corretamente
    printf("Arquivo organizado. ");
    pausa();
    return;
}
void excluir(){//Função que procura um contato, se o encontrar troca todas as letras do campo de esse contato por asteriscos'*'.
	
	
	limparTela();
	//Abrimos em modo leitura estendido a W
	FILE* arquivo = fopen("agenda.txt", "r+");
	if(arquivo == NULL){
        printf("Nao foi possivel abrir o arquivo para excluir o contato");
        return;
	}
	Agenda contato;              //Variavel auxiliar
	bool encontrado = false;	//flag... vira true quando o nome é encontrado
	fpos_t antesDeUsuario = 0; //Variavel que vai conter a posição do inicio de cada linha.
	
	//perguntamos por qual contato queremos eliminar
	printf("Nome do contato a excluir?: ");
	char nome[50] = {0};
	scanf("%s%*c",nome);
	limparTela();
    
    //buscamos no arquivo o usuario tomado anteriormente por teclado
	rewind(arquivo);
    fgetpos( arquivo, &antesDeUsuario);
    while ( lerDadosArquivo( arquivo, &contato ) != EOF ){
        if ( strcmp(nome, contato.nome) == 0 ){
            encontrado = true;
            break;
        }
        fgetpos( arquivo, &antesDeUsuario); 
	}
	
	//Si o contato existe excluimos ele transformando suas letras em asteriscos'*' deixando marcado no arquivo, pois o espaço permanece em branco, por isso devemos marcar com *, para posteriormente eliminar esses espaços com *** *** ao organizar o arquivo.
	if ( encontrado == true ){
        char linha[200] = {0};
        fsetpos( arquivo, &antesDeUsuario );
        fgets(linha,200, arquivo);
        
        //Subistituindo todas as letras por *
        for( int i = 0; linha[i] != '\0'; i++ ){
            if ( linha[i] != ' ' && linha[i] != '\r' && linha[i] != '\n' ){
                linha[i] = '*';
            }
        }
        fsetpos( arquivo, &antesDeUsuario );
        fputs(linha, arquivo);
        fclose(arquivo);
        
        printf("Contato excluido. ");
        pausa();
        limparTela();
        return;
	
	
	}else{ //Si o usuario não estiver no arquivo avisamos e saimos sem alterar nada.
        limparTela();
        printf("Não existe esse contato. ");
        pausa();
        fclose(arquivo);
        return;
	}
	//Fin da função.
}

//Implementação funções básicas
int  menu( int opc ){
    //Esse é o menu de opções
    limparTela();
    printf("Escolha uma opção \n1-Incluir \n2-Listar \n3-Ordenar \n4-Excluir \n0-Sair \n?>>");
    scanf(" %d%*c",&opc );
    return opc; //<-retorna a opção para o switch desde aqui a main deixando a mesma más organizada.
}
void tomarDadosContato  ( Agenda* contato ){
	//Pede ao usuario os dados do contato a incluir ao arquivo e guarda ele no contato recebido por referencia.
	printf("Entre com os dados do usuario\n\n");
	printf ("Nome....: "); scanf ( "%s%*c", contato->nome );
	printf ("Tel fixo: "); scanf ( "%d%*c", &contato->telefoneFixo );
	printf ("Tel cel.: "); scanf ( "%d%*c", &contato->telefoneCelular );
	printf ("e-mail..: "); scanf ( "%s%*c", contato->email );
	return;    
}
int  lerDadosArquivo    ( FILE* arquivo, Agenda* contato ){
    //Le um usuario por vez, e se chega no fim do arquivo retorna EOF(fim do arquivo.). É uma versao más curta do fscanf praticamente.
    return fscanf ( arquivo, "%s %d %d %s%*c", contato->nome, &contato->telefoneFixo, &contato->telefoneCelular, contato->email );
} 
void imprimirContato    ( Agenda* contato ){
    //imprime o contato recebido por referencia.
    printf("%s %d %d %s\n", contato->nome, contato->telefoneFixo, contato->telefoneCelular, contato->email);
    return;
}
void guardarDadosArquivo( FILE* arquivo, Agenda* contato ){
    //Escreve os dados do contato tomados previamente normalmente por tomarDadosContato na posiçao atual em que esteja o descritor de archivo ou tambem chamado cursor.
    fprintf( arquivo, "%s %d %d %s\n", contato->nome, contato->telefoneFixo, contato->telefoneCelular, contato->email );
    return;
}
void pausa(){
    //pausa o programa. É melhor opção que usar system("pause"); já que nao precisamos incluir más headers.
    printf("Presione uma tecla para continuar...");
    scanf("%*c");
    return;
}
void limparTela(){
    //bastante obvio que limpa nossa tela só no windows. si estamos en linux é só incluir aqui a funçao que limpa tela no linux ;)
    
    //v1
    //COORD inicio = {0, 0};
    //int linhas = 100;
    //int colunas = 60;
    //DWORD n;
    //FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ', linhas*colunas, inicio, &n);
    
    //v2
    COORD coord;
    DWORD written;
    CONSOLE_SCREEN_BUFFER_INFO info;
    
    coord.X = 0;
    coord.Y = 0;
    GetConsoleScreenBufferInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &info );
    FillConsoleOutputCharacter ( GetStdHandle ( STD_OUTPUT_HANDLE ), ' ',
    info.dwSize.X * info.dwSize.Y, coord, &written );
    SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ), coord );
    return;
}
void copiar( Agenda* A, Agenda* B ){
    //Copia contato A em contato B recebido por punteiros.
    strcpy( B->nome, A->nome );
    B->telefoneFixo = A->telefoneFixo;
    B->telefoneCelular =A->telefoneCelular;
    strcpy( B->email, A->email ); 
}

Aqui te deixo um exemplo que fiz a muito tempo

adicionado 3 minutos depois

costumo abrir e fechar o arquivo na mesma função... tipo se vou ler algum dado e tenho uma função para isso, o que faço é abrir em modo leitura dentro dessa função, faço a leitura dos dados e fecho o arquivo. Faço isso assim porque só dessa forma garanto que os dados estão salvos corretamente. É muito mais complicado desde meu ponto de vista usar um só ponteiro para todas as operações, pois se falhar uma vez e você insistir em usa-lo pode ser muito critico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

comece pela função incluir, entenda ela completamente. Verifique o arquivo de saida a cada operação que fizer, para ver o que está acontecendo em cada momento.

adicionado 0 minutos depois

É possível melhorar isso e muito ainda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

sim, estou exatamente nela, não tava achando as modularizações e vi que estava em baixo kk

adicionado 2 minutos depois

só não entendi onde você retorna a função no int main. não tem nenhuma variável retornando o valor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×