Jump to content

Problemas com a Linguagem C


francisco esley

Recommended Posts

Estou realizando um trabalho onde é pedido isso: 

O sistema a ser construído necessitará atender aos requisitos funcionais abaixo:

1 - Possuir a sua identificação (RA-Nome-Curso)
2 - Possuir um menu de opção.
2.1 - Incluir o registro das obras.
2.2 - Listar todos os livros.
2.3 - Listar todas as revistas.
2.4- Listar as obras por caixa.

Porém o meu código está com um problema de que quando eu dou um espaço na hora de cadastrar, ele armazena a informação correta porém lê de forma errada.Suponhamos que eu queira cadastrar o título e o autor de uma certa obra, tenho então os campos Autor e Título do livro do livro, certo? Porém quando dou um espaço entre primeiro e segundo nome eles ficam separados na hora da leitura do arquivo txt, por exemplo: ao invés de ficar "Autor: Francisco Esley (meu nome) e Título do livro: Engenharia de software", ele lê certo até o espaço e depois vai para a outra variável ficando assim: "Autor: Francisco Título do livro: Esley". Não sei mais o que fazer... Aqui está o código que desenvolvi para darem uma olhada:

void menu(){
    printf ("\n\n1 - Cadastrar\n");
    printf ("2 - Listar todos os livros.\n");
    printf ("3 - Listar todas as revistas.\n");
    printf ("4 - Listar as obras por caixa.\n");
    printf ("0 - Sair\n");
}

FILE* AbreArquivo(char modo, char caminho[100]){
    FILE *arquivo;
    switch(modo){

        case 'g':
            arquivo = fopen(caminho,"wt");
            break;
        case 'l':
            arquivo = fopen(caminho,"rt");
            break;
        case 'a':
            arquivo = fopen(caminho,"a");
            break;
    }

    if(arquivo==NULL){

        printf("Nao foi possivel abrir o arquivo");
        exit(0);

    }

    return arquivo;
}

void FecharArquivo(FILE *arquivo){

    fclose(arquivo);

}

void Cadastra(char titulo[70],char editora[70], char autor[70], int caixa, int ano, int ISBN){

    FILE *arquivo;
    arquivo = AbreArquivo('a', "mapa.txt");
    fprintf(arquivo, "%s %s %s %d %d %d\n", titulo, autor, editora, caixa, ano, ISBN);

    FecharArquivo(arquivo);
}

void CadastraRevista(char titulo[70],char editora[70], char autor[70], int caixa, int ano, int ISBN){

    FILE *arquivo;
    arquivo = AbreArquivo('a', "mapa.txt");
    fprintf(arquivo, "%s %s %s %d %d %d\n", titulo, autor, editora, caixa, ano, ISBN);
    FecharArquivo(arquivo);
}

void Listar(){

    FILE *arquivo;
    char titulo[70];
    char autor[70];
    char editora[70];
    int caixa;
    int ano;
    int ISBN;

    arquivo = AbreArquivo('l',"mapa.txt");

    while(!feof(arquivo)){

        fscanf(arquivo,"%s %s %s %d %d %d ", &titulo, &autor, &editora, &caixa, &ano, &ISBN);
        setbuf(stdin,NULL);
        for(int i=0; i<120; i++)printf ("*");
        printf("\n\nTitulo: %s   -  Autor: %s  - Editora: %s  - Caixa: %d  - Ano: %d  - ISBN: %d\n\n\n", titulo,editora ,autor , caixa, ano, ISBN);

    }
    FecharArquivo(arquivo);
}

int main(){

    char titulo[70];
    char autor[70];
    char editora[70];
    int caixa;
    int ano;
    int ISBN;
    int opcao;


    
    menu();
    do{

        printf("\nDigite uma opcao: ");
        scanf("%d", &opcao);
        system("cls");

        switch(opcao){
            case 1:

                printf("\nDigite o titulo: ");
                setbuf(stdin,NULL);
                scanf("%[^\n]s",titulo);

                printf("\nDigite o autor: ");
                setbuf(stdin,NULL);
                fgets(autor,70, stdin);

                printf("\nDigite o editora: ");
                setbuf(stdin,NULL);
                fgets(editora, 70,stdin );

                printf("\nDigite a caixa: ");
                scanf("%d", &caixa);

                printf("\nDigite o ano: ");
                scanf("%d", &ano);

                printf("\nDigite o ISBN: ");
                scanf("%d", &ISBN);
                Cadastra(titulo, autor, editora, caixa, ano, ISBN);
                system("pause");
                break;

            case 2:
                Listar();
                system("pause");
                break;

            case 3:
                Listar();
                system("pause");
                break;

            case 4:
                Listar();
                system("pause");
                break;

            case 5:
                printf("Finalizando......\n");
                system("pause");
                exit(0);

            default:
                printf("\n\nOpcao invalida! Tente Novamente!\n\n");
                system("pause");

        }
    }while(opcao!=3);

    return 0;
}
Link to comment
Share on other sites

O ficheiro mapa.txt não guarda a informação da forma como correta como julgas.
Efetivamente guarda tudo, mas devias ter uma linha por registo, e vais ficar com umas 4 linhas por registo, o que é errado.
Isso acontece porque não limpas o cr/lf do input do utilizador.
Quando vais ler a informação do ficheiro, a linha não tem a estrutura que acreditas ter, e por isso ficas com a leitura "estragada".

Eliminas o "new line" do input do utilizador (nas strings) e em principio deverás ter o problema resolvido.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other sites

37 minutos atrás, M6 disse:

O ficheiro mapa.txt não guarda a informação da forma como correta como julgas.
Efetivamente guarda tudo, mas devias ter uma linha por registo, e vais ficar com umas 4 linhas por registo, o que é errado.
Isso acontece porque não limpas o cr/lf do input do utilizador.
Quando vais ler a informação do ficheiro, a linha não tem a estrutura que acreditas ter, e por isso ficas com a leitura "estragada".

Eliminas o "new line" do input do utilizador (nas strings) e em principio deverás ter o problema resolvido.

Problema ainda insiste em ocorrer, tentei o que me disseste mas não estou conseguindo fazer o que é pedido no trabalho, estou a ficar "maluco".

Link to comment
Share on other sites

9 horas atrás, francisco esley disse:

Problema ainda insiste em ocorrer, tentei o que me disseste mas não estou conseguindo fazer o que é pedido no trabalho, estou a ficar "maluco".

tens mesmo de usar um ficheiro texto?

não era muito mais fácil e robusto, criar um struct "obra" com toda a informação que pretendes guardar/ler e usar um ficheiro binário.

p/f veja este exemplo https://www.geeksforgeeks.org/readwrite-structure-file-c/

Link to comment
Share on other sites

4 horas atrás, antseq disse:

tens mesmo de usar um ficheiro texto?

não era muito mais fácil e robusto, criar um struct "obra" com toda a informação que pretendes guardar/ler e usar um ficheiro binário.

p/f veja este exemplo https://www.geeksforgeeks.org/readwrite-structure-file-c/

Irei tentar sua dica, parece que vai resolver. E sim, tenho que usar um ficheiro texto pois o professor da faculdade pediu, logo mais retorno para informa se resolveu meu problema.

Link to comment
Share on other sites

10 horas atrás, antseq disse:

tens mesmo de usar um ficheiro texto?

não era muito mais fácil e robusto, criar um struct "obra" com toda a informação que pretendes guardar/ler e usar um ficheiro binário.

p/f veja este exemplo https://www.geeksforgeeks.org/readwrite-structure-file-c/

Sim sua dica realmente é boa e funcional porém verifiquei e infelizmente tens que ser o ficheiro texto. Obrigado pela dica, acho que irei entregar me trabalho assim infelizmente, pegarei a nota parcial.

Link to comment
Share on other sites

1 hora atrás, francisco esley disse:

Sim sua dica realmente é boa e funcional porém verifiquei e infelizmente tens que ser o ficheiro texto. Obrigado pela dica, acho que irei entregar me trabalho assim infelizmente, pegarei a nota parcial.

Dos tempos em que programava em C/C++ acho que nunca li um ficheiro com "fscanf"... nomeadamente para estruturas (objectos) bem definidos usava um "struct" e um ficheiro binário...

Em todo o caso, achei curioso o desafio de ficar em texto e dado que ficam 3 strings juntas, das duas uma, ou tinham de ficar num ficheiro com colunas de tamanho fixo ou tinham de ter algum caracter delimitador entre elas. Estive a experimentar com um delimitador ";" e parece funcionar !

Fica aqui o código, sem garantias, pode ser que alguém o consiga melhorar.

Apenas modifiquei o fprintf e o fscanf:

void CadastraRevista(char titulo[70],char editora[70], char autor[70], int caixa, int ano, int ISBN){
    FILE *arquivo;
    arquivo = AbreArquivo('a', "mapa.txt");
    fprintf(arquivo, "%s;%s;%s;%d %d %d\n", titulo, autor, editora, caixa, ano, ISBN);
    FecharArquivo(arquivo);
}
void Listar(){
    FILE *arquivo;
    char titulo[70];
    char autor[70];
    char editora[70];
    int caixa;
    int ano;
    int ISBN;
    arquivo = AbreArquivo('l',"mapa.txt");
    while(6 == fscanf(arquivo,"%70[^;];%70[^;];%70[^;];%d %d %d\n", &titulo, &autor, &editora, &caixa, &ano, &ISBN)){
        setbuf(stdin,NULL);
        printf("\nTitulo: %s -  Autor: %s  - Editora: %s  - Caixa: %d  - Ano: %d  - ISBN: %d", titulo,editora ,autor , caixa, ano, ISBN);
    }
    FecharArquivo(arquivo);
}

int main()
{
  	//EXEMPLO
    CadastraRevista("Portugal a programar #1", "Editora 1", "Nome do Autor #1", 1, 2001, 9000001);
    CadastraRevista("Portugal a programar #2", "Editora 2", "Nome do Autor #2", 1, 2002, 9000002);
    CadastraRevista("Portugal a programar #3", "Editora 3", "Nome do Autor #3", 1, 2003, 9000003);
  
    Listar();
    //OUTPUT
    //Titulo: Portugal a programar #1 -  Autor: Editora 1  - Editora: Nome do Autor #1  - Caixa: 1  - Ano: 2001  - ISBN: 9000001                       
    //Titulo: Portugal a programar #2 -  Autor: Editora 2  - Editora: Nome do Autor #2  - Caixa: 1  - Ano: 2002  - ISBN: 9000002                       
    //Titulo: Portugal a programar #3 -  Autor: Editora 3  - Editora: Nome do Autor #3  - Caixa: 1  - Ano: 2003  - ISBN: 9000003
  
    return 0;
}
  • Vote 1
Link to comment
Share on other sites

4 horas atrás, antseq disse:

Dos tempos em que programava em C/C++ acho que nunca li um ficheiro com "fscanf"... nomeadamente para estruturas (objectos) bem definidos usava um "struct" e um ficheiro binário...

Em todo o caso, achei curioso o desafio de ficar em texto e dado que ficam 3 strings juntas, das duas uma, ou tinham de ficar num ficheiro com colunas de tamanho fixo ou tinham de ter algum caracter delimitador entre elas. Estive a experimentar com um delimitador ";" e parece funcionar !

Fica aqui o código, sem garantias, pode ser que alguém o consiga melhorar.

Apenas modifiquei o fprintf e o fscanf:


void CadastraRevista(char titulo[70],char editora[70], char autor[70], int caixa, int ano, int ISBN){
    FILE *arquivo;
    arquivo = AbreArquivo('a', "mapa.txt");
    fprintf(arquivo, "%s;%s;%s;%d %d %d\n", titulo, autor, editora, caixa, ano, ISBN);
    FecharArquivo(arquivo);
}
void Listar(){
    FILE *arquivo;
    char titulo[70];
    char autor[70];
    char editora[70];
    int caixa;
    int ano;
    int ISBN;
    arquivo = AbreArquivo('l',"mapa.txt");
    while(6 == fscanf(arquivo,"%70[^;];%70[^;];%70[^;];%d %d %d\n", &titulo, &autor, &editora, &caixa, &ano, &ISBN)){
        setbuf(stdin,NULL);
        printf("\nTitulo: %s -  Autor: %s  - Editora: %s  - Caixa: %d  - Ano: %d  - ISBN: %d", titulo,editora ,autor , caixa, ano, ISBN);
    }
    FecharArquivo(arquivo);
}

int main()
{
  	//EXEMPLO
    CadastraRevista("Portugal a programar #1", "Editora 1", "Nome do Autor #1", 1, 2001, 9000001);
    CadastraRevista("Portugal a programar #2", "Editora 2", "Nome do Autor #2", 1, 2002, 9000002);
    CadastraRevista("Portugal a programar #3", "Editora 3", "Nome do Autor #3", 1, 2003, 9000003);
  
    Listar();
    //OUTPUT
    //Titulo: Portugal a programar #1 -  Autor: Editora 1  - Editora: Nome do Autor #1  - Caixa: 1  - Ano: 2001  - ISBN: 9000001                       
    //Titulo: Portugal a programar #2 -  Autor: Editora 2  - Editora: Nome do Autor #2  - Caixa: 1  - Ano: 2002  - ISBN: 9000002                       
    //Titulo: Portugal a programar #3 -  Autor: Editora 3  - Editora: Nome do Autor #3  - Caixa: 1  - Ano: 2003  - ISBN: 9000003
  
    return 0;
}

Certo, funcionou porém não estava retornando na tela, consegui fazer com que mostrasse na tela porém está bagunçado, poderia dar uma olhada? http://prntscr.com/t3lahu 

Desculpa se eu estiver incomodando vocês porém com essa pandemia está bem difícil entender as aulas via internet, e estou desesperado para conseguir fazer um bom trabalho.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.