Ir ao conteúdo
  • Cadastre-se

C opa, eu to tentando fazer um codigo que pelo que eu vi é bem comum de se achar p


yooe

Posts recomendados

opa, eu to tentando fazer um codigo que pelo que eu vi é bem comum de se achar pela interne para uma cadeira de Iniciação a computação, eu ainda to no começo dele, não fiz erros nem verificação de login nem nada de mais ainda, eu to com um problema que é eu crio um arquivo com o fopen que vai ser nomeado pelo usuário, sendo que ele não cai na pasta certa, eu tentei fazer um caminho para ele no próprio fopen e não consegui e tentei mover ele, sendo que todas as opções que eu achei tinha que saber o nome do arquivo previamente para poder mover ele, e eu não consegui fazer isso com a variável que armazena o dado do login. 
eu uso o vscode.



 

#include <stdio.h>

#include <stdlib.h>

#include <locale.h>



int interface_menu();

void menu_1();

void engine();

void menu_2();

FILE *z;



int main()



{

 int menu0;



    do

    {

        menu0=interface_menu();

        engine(menu0);

    }

    while(menu0!=4);

return 0;

}



int interface_menu()

{

int N_menu;



    printf("informe para onde você que ir \n");

    printf(" 1- cadastrar \n 2- alterar as suas informacoces \n 3- verificar a lista de cadastrados \n 4- para finalizar\n");

    scanf("%d", &N_menu);



return N_menu;

}



void menu_1()

{



 char login[101];

 char nome[101];

 char nomeData;

 char matricula[13];

 char DDD[3];

 char telefone[10];

 char cpf[13];

 char idade[3];



    printf("agora vamos pegar algumas de suas informações\ndigite o seu login: \n");

    gets(login);

    gets(login);

//por que tem 2 gets ??? https://www.clubedohardware.com.br/forums/topic/634801-resolvido-porque-o-dev-esta-pulando-o-comando-gets/

    z=fopen(login, "w");



    printf("digite o seu nome\n");

    gets(nome);

    printf("digite a sua matricula\n");

    gets(matricula);

   

   

    printf("digite o DDD\n");

    gets(DDD);

    printf("agora digite o seu numero de telefone\n");

    gets(telefone);

   

    printf("digite o seu cpf\n");

    gets(cpf);



    printf("digite a sua idade\n");

    gets(idade);

   

    // Colocando no arquivo as informações

   

    fprintf(z,"Nome:%s\n",nome);

    putc('\n', z);



    fprintf(z,"Matricula:%s",matricula);

    putc('\n', z);



    fprintf(z,"DDD:%s",DDD);

    putc('\n', z);



    fprintf(z,"Telefone:%s",telefone);

    putc('\n', z);



    fprintf(z,"cpf:%s",cpf);

    putc('\n', z);



    fprintf(z,"idade:%s",idade);

    putc('\n', z);

    fclose;

   

return;

}

void menu_2()

{



}



void engine(int N_menu)

{

//int erro1;



    if(N_menu==1)

    {  

        menu_1();

    }

    else if(N_menu==2)

    {

        menu_2();

    }



}

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

@yooe     

2 horas atrás, yooe disse:

eu crio um arquivo com o fopen que vai ser nomeado pelo usuário, sendo que ele não cai na pasta certa

esse arquivo não " cai " em nenhuma pasta , por que se realmente tiver sido criado , e preenchido com os dados enviados por fprintf ,  mesmo assim a gravação dele só será efetivada ao usar o fclose() , mas precisa especificar o nome da variável em esteja o arquivo , o FILE*  que no seu código seria assim  :

 

fprintf(
           z,                       
            "Nome ------: %s\
           \rMatricula -: %s\
           \rDDD -------: %s\      
           \rTelefone --: %s\
           \rcpf -------: %s\
           \ridade -----: %s", 
           nome,  matricula , DDD,  // as variaveis
           telefone, cpf, idade 
       );
fclose(z); // inf nome do arq para validar gravação

 

Link para o comentário
Compartilhar em outros sites

@devair1010
valeu ai por ter deixado mais clean o código e ter alertado sobre o fclose(z), tipo o que tá acontecendo é que esse arquivos estão sendo criados dentro da pasta de origem do programa com arquivos sem um .algumacoisa depois dele(no caso era pra ser .txt) mas se você abrir com o bloco de notas ele abre normalmente com as informações todas, eu to com uma pasta dentre da pasta que ta rodando o programa chamada alunos onde eu vou guardar as informações de cada pessoa que estiver lá e eu planejo fazer um sistema pra não sobre escrever nada e não permitir a entrada de dois arquivos com o mesmo nome resultando em um ser deletado ou ficar com o numero 2 depois dele, to usando a biblioteca "dirent.h" pra isso.

eu só to um pouco confuso ainda em como eu vou mover esses arquivos de uma pasta para a outra e também como cria-los já sendo um .txt ou mudar para isso, mas eu ainda to testando pra ver se da pra ler eles sem a necessidade disso.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

eu crio um arquivo com o fopen que vai ser nomeado pelo usuário


Não sei se entendo o modo como escreve, mas

  • parece que está ao contrário: o usuário vai fornecer o nome do arquivo a ser criado, mas não a extensão ou a pasta, e você quer uma certa extensão, TXT ao que parece, e uma certa pasta. `fopen()` espera o nome completo do arquivo, então apenas monte o nome de acordo, ANTES de passar para `fopen()`. Só isso.

sendo que ele não cai na pasta certa
 

  • arquivos não "caem" em pastas. O arquivo será aberto usando o nome que está no parâmetro. Se contiver uma pasta ou mesmo --- no caso do Windows --- uma letra de drive é isso que vai ser usado. O mesmo vale para a extensão.
     

eu tentei fazer um caminho para ele no próprio fopen

Não é o caso. `fopen()` espera dois parâmetros
 

    FILE *fopen(const char *filename, const char *mode)


apenas monte de acordo

e tentei mover ele

- para mover --- se usa Windows --- pode usar o simples: MoveFile()`. São só dois parâmetros, os que você imagina: o nome original e o novo. Retorna `0` se deu erro.

Qual a razão para usar espaço duplo? Alinhe melhor o código. Isso ajuda você e outros.

 

Veja um exemplo:
 

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
int   interface_menu();
void  menu_1();
void  engine();
void  menu_2();
FILE* z;
int   main()
{
    int menu0;
    do {
        menu0 = interface_menu();
        engine(menu0);
    } while (menu0 != 4);
    return 0;
}
int interface_menu()
{
    int N_menu;
    printf("informe para onde você que ir \n");
    printf(
        " 1- cadastrar \n 2- alterar as suas informacoces \n 3- "
        "verificar a lista de cadastrados \n 4- para finalizar\n");
    scanf("%d", &N_menu);
    return N_menu;
}
void menu_1()
{
    char login[101];
    char nome[101];
    char nomeData;
    char matricula[13];
    char DDD[3];
    char telefone[10];
    char cpf[13];
    char idade[3];
    printf(
        "agora vamos pegar algumas de suas informações\ndigite o seu "
        "login: \n");
    gets(login);
    gets(login);
    // por que tem 2 gets ???
    // https://www.clubedohardware.com.br/forums/topic/634801-resolvido-porque-o-dev-esta-pulando-o-comando-gets/
    z = fopen(login, "w");
    printf("digite o seu nome\n");
    gets(nome);
    printf("digite a sua matricula\n");
    gets(matricula);
    printf("digite o DDD\n");
    gets(DDD);
    printf("agora digite o seu numero de telefone\n");
    gets(telefone);
    printf("digite o seu cpf\n");
    gets(cpf);
    printf("digite a sua idade\n");
    gets(idade);
    // Colocando no arquivo as informações
    fprintf(z, "Nome:%s\n", nome);
    putc('\n', z);
    fprintf(z, "Matricula:%s", matricula);
    putc('\n', z);
    fprintf(z, "DDD:%s", DDD);
    putc('\n', z);
    fprintf(z, "Telefone:%s", telefone);
    putc('\n', z);
    fprintf(z, "cpf:%s", cpf);
    putc('\n', z);
    fprintf(z, "idade:%s", idade);
    putc('\n', z);
    fclose;
    return;
}
void menu_2() {}
void engine(int N_menu)
{
    // int erro1;
    if (N_menu == 1) { menu_1(); }
    else if (N_menu == 2)
    {
        menu_2();
    }
}


Sobre o programa

Tem muitos problemas ainda. Vai ter muito trabalho (evitável) se continuar escrevendo assim.

 

  • não use `gets()` nunca. Isso não existe há décadas e muitos compiladores nem aceitam mais. E muitas escolas e empresas também 😉 Esqueça isso. Use `fgets()`. É muito melhor.
  • não use void: retorne algo. Nem use (void). Passe parâmetros. É muito mais simples.
  • não use globais. Nunca
  • use nomes significativos
    void menu_1();
    void engine();
    void menu_2();


Evite a todo custo:

  • um menu retorna uma opção.
  • engine() aí é problemático
    int   main()
    {
        int menu0;
        do {
            menu0 = interface_menu();
            engine(menu0);
        } while (menu0 != 4);
        return 0;
    }

    Esse é o seu programa principal.

Qual a vantagem de ter a lógica toda em engine() e depois retornar apenas para encerrar o programa?

Só fica mais difícil de ler. E se `menu0` é só uma opção porque não usar um nome de acordo, tipo... `opt`, `opcao`?

Mais ainda. isso é o mesmo que escrever
 

    int main()
    {
        do { engine(interface_menu()); } while ( 1 );
        return 0;
    }


Qual é mais fácil de entender?
 

E engine() ?
 

void engine(int N_menu)
{
    // int erro1;
    if (N_menu == 1) { menu_1(); }
    else if (N_menu == 2)
    {
        menu_2();
    }
}


Está bem confuso. Porque não passa um parâmetro para uma única função menu() então?

 

    void engine(int n) { menu(n); };


Não é mais simples? E porque não retorna a opção do tal menu, como em 

 

int engine(int n) { return menu(n); };

 

E assim já pode ir tratando a opção do menu() fora da lógica dos menus?

 

 

E se olhar de novo o código de `main()` que chama `engine()` que chama `menu()` vai ver que não está avançando muito com essa estrutura...

 

 

TESTE sempre o retorno de `scanf()`. É ingênuo seguir adiante se não leu nada, por exemplo.
 

    // Colocando no arquivo as informações
    fprintf(z, "Nome:%s\n", nome);
    putc('\n', z);
    fprintf(z, "Matricula:%s", matricula);
    putc('\n', z);
    fprintf(z, "DDD:%s", DDD);
    putc('\n', z);
    fprintf(z, "Telefone:%s", telefone);
    putc('\n', z);
    fprintf(z, "cpf:%s", cpf);
    putc('\n', z);

 

Evite acentos em comentários. Não acrescenta nada e pode ficar ruim de ler em outros computadores.

Que pretende com essas linhas? Em especial os putc()? Para que isso?

Use um título mais significativo, que possa ajudar outros com um problema semelhante. Esse é o propósito do forum. 

 

Não acha que algo como "Usando fopen() em C para escolher a pasta do arquivo" seria melhor por exemplo?

Use um título mais significativo, que possa ajudar outros com um problema semelhante. Esse é o propósito do forum. 

 

Não acha que algo como "Usando fopen() em C para escolher a pasta do arquivo" seria melhor por exemplo? Assim alguém que usasse a busca do Google poderia chegar até a questão...

  • Amei 1
Link para o comentário
Compartilhar em outros sites

@arfneto  obrigado pela ajuda eu consegui progredir com o código agora de noite!!!
eu só to tendo problemas com o fgets, toda vez que eu coloco ele o programa para de funcionar, então eu deixei no gets por hora, depois eu procuro  uma solução, quanto aos espaços por algum motivo quando eu olhei agora eles tão dobrados e triplicados e um deles até estava quadriplicado, não sei o que aconteceu, mas obrigado mesmo assim eu tirei os espaços do meu texto, eu não pretendo fazer esse role que você falou na engine() porque ela vai tratar de erros e outras coisas também, não só os menus, eu só não tive tempo de fazer ainda. eu pretendo colocar as limitações de inputs e alguns erros que eu consigo pensar pra fazer esse programa, quanto ao int main() que você sugeriu ele não funciona no meu programa, talvez pela forma esquisita que eu escrevo.

o programa tá assim agora se você quiser saber:
 

#include "stdio.h"
#include "stdlib.h"
#include "locale.h"
#include "string.h" 
#include "dirent.h"   //para poder pesquisar em apastas.
int interface_menu();
int menu_1();
int engine();
int menu_2();
FILE *z;
int main()
{
 int opt;
  do
  {
    opt=interface_menu();
    engine(opt);
  }
  while(opt!=4);
return 0;
}

int interface_menu()
{
 int N_menu;
    printf("informe para onde você que ir \n");
    printf(" 1- cadastrar \n 2- alterar as suas informacoces \n 3- verificar a lista de cadastrados \n 4- para finalizar\n");
    scanf("%d", &N_menu);
return N_menu;
}
int menu_1()
{
 char login[101];
 char nome[101];
 char matricula[13];
 char DDD[3];
 char telefone[10];
 char cpf[13];
 char idade[3];
 
  printf("agora vamos pegar algumas de suas informações\ndigite o seu login: \n");
  gets(login);
  gets(login);
 //por que tem 2 fgets ??? https://www.clubedohardware.com.br/forums/topic/634801-resolvido-porque-o-dev-esta-pulando-o-comando-gets/
 char local_inicial[100] ="C:\\Users\\davic\\Desktop\\Lista de livros da ufpb\\P5\\prova 3 C\\";
 char local_final[100] = "C:\\Users\\davic\\Desktop\\Lista de livros da ufpb\\P5\\prova 3 C\\alunos\\";
  strcat(local_inicial, login);
  strcat(local_final, login);
  strcat(local_final,".txt");
  z=fopen(login, "w");
  //obtendo os dados
  printf("digite o seu nome\n");
  gets(nome);
  printf("digite a sua matricula\n");
  gets(matricula);
  printf("digite o DDD\n");
  gets(DDD);
  printf("agora digite o seu numero de telefone\n");
  gets(telefone);
  printf("digite o seu cpf\n");
  gets(cpf);
  printf("digite a sua idade\n");
  gets(idade);
  // Colocando no arquivo as informações
  fprintf(z,"Nome:%s\n\nMatricula:%s\nDDD:%s\nTelefone:%s\ncpf:%s\nidade:%s\n",nome,matricula,DDD,telefone,cpf,idade);
  fclose(z);
  rename(local_inicial, local_final);
return 0;
}
int menu_2()
{
 char login;
    printf("por favor digite o seu login\n");
    scanf("%c", &login);
    scanf("%c", &login);
     DIR *dir;
   struct dirent *ent;
   if ((dir = opendir ("C:\\Users\\davic\\Desktop\\Lista de livros da ufpb\\P5\\prova 3 C\\alunos"))!= NULL) 
   {
     /* print all the files and directories within directory */
     while ((ent = readdir (dir)) != NULL) {
       printf ("%s\n", ent->d_name);
     }
     closedir (dir);
   } 
   else 
   {
     /* could not open directory */
     perror ("");
   return;
  }
  
    if((z=fopen(login, "r+"))==-1)
    {
        printf("esse login não existe");
    }
}
int engine(int N_menu)
{
  if(N_menu==1)
  {
    menu_1();
  }
  else if(N_menu==2)
  {
    menu_2();
  }
return 0; 
}


no menu dois eu vou fazer a listagem dos arquivos .txt e comparação do login com digitado para ai então abrir a pasta de substituir as informações.
ainda tem um menu 3 que eu tenho que listar todos os dados num printf ou em outro arquivo pra ficar organizadinho, pensei até em usar o execel, mas acho que eu só vou estar colocando trabalho de mais pra ser feito, e deoius eu vou para lidar com os erros e imposição dos limites dos inputs.
minha duvida toda com isso era só o comando strcat que eu não conhecia e eu acabei resolvendo por rename pra não ficar fugindo tanto das bibliotecas padrão.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

10 minutos atrás, yooe disse:

role

 

Isso define bem o modo como escreveu, uma função que não faz nada chama outra que não faz nada que chama outra que começa o programa. Acho que percebeu que a função main(0 está vazia, engine não faz quase nada e menu devia retornar uma opção...

 

11 minutos atrás, yooe disse:

problemas com o fgets, toda vez que eu coloco ele o programa para de funcionar, então eu deixei no gets por hora, depois eu procuro  uma solução, quanto aos espaços por algum motivo quando eu olhei agora eles tão dobrados e triplicados e um deles até estava quadriplicado, não sei o que aconteceu

 

Não sou seu instrutor ou seu patrão :) . Nem seu compilador. Se eu fosse você não usaria gets(). Entenda: essa rotina não existe há décadas. Foi marcada obsoleta apenas para não criar problemas. É uma ideia besta não poder dizer o tamanho do campo. E essa é a diferença para fgets(). Só essa. Isso não é a causa de seu erro. Seu programa não está bom. Vai levar uma eternidade para ele funcionar se insiste nesse mecanismo. E

  • vai ter dificuldade em aproveitar qualquer coisa desse programa no futuro
  • vai passar adiante o momento de fazer as coisas de um modo mais eficiente. Sempre vai cair na sua cabeça isso.
15 minutos atrás, yooe disse:

int main() que você sugeriu ele não funciona no meu programa, talvez pela forma esquisita que eu escrevo.

Não consegui entender ...

 

Nunca escreva um programa interativo.  Só vai te atrasar. Escreva e teste tudo. Não misture menus e entrada de dados com a lógica. Só vai perder muito tempo. Não escreva assim. Depois que estiver ok você coloca a tal interatividade. 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

19 horas atrás, devair1010 disse:

esse arquivo não " cai " em nenhuma pasta , por que se realmente tiver sido criado , e preenchido com os dados enviados por fprintf ,  mesmo assim a gravação dele só será efetivada ao usar o fclose()

 

Não funciona assim. Não é o fclose() que efetiva a gravação. O sistema escolhe a hora de fazer isso. É a noção de buffer. Claro, um fclose() vai forçar essa gravação, como uma chamada a fflush() no arquivo faria. Essa é a razão de fflush() existir: dar ao programa a possibilidade de esvaziar o buffer, que pode já estar vazio, completando as operações pendentes, num dado e preciso momento.

 

No geral o programador não se preocupa com isso, mas há casos em que isso é importante.

 

 

5 horas atrás, yooe disse:
    char local_inicial[100] ="C:\\Users\\davic\\Desktop\\Lista de livros da ufpb\\P5\\prova 3 C\\";
    char local_final[100] =  "C:\\Users\\davic\\Desktop\\Lista de livros da ufpb\\P5\\prova 3 C\\alunos\\";
 

 

 

apesar de ter esses valores em opendir aparece

 

    if ((dir = opendir("C:\\Users\\davic\\Desktop\\Lista de livros da "
                       "ufpb\\P5\\prova 3 C\\alunos")) != NULL)

 

Note:

  • provavelmente estaria melhor servido com
    • '.' para indicar o diretório corrente, ou nada, já que é o padrão
    • não precisa repetir os \\ por causa do Windows, pode usar simplesmente a barra,  '/' , está no manual
    • uma variável com a pasta dos alunos seria bem conveniente, em especial para testar, porque não ia precisar ficar copiando arquivos e poderia manter pastas separadas com cenários de teste separados
  • usar um arquivo para cada aluno é possível, mas é complicado
    • é muito chato para controlar
    •  demora demais
    • uma simples listagem de alunos é um pesadelo
    • o simples seria criar um arquivo de alunos como todo mundo. 
      • e no início do programa copia os alunos do arquivo para um vetor ou uma lista
      • ao final do programa grava a versão atual no disco a partir do vetor
      • pode usar arquivo texto, ou binário, ou um simples CSV separando os campos por ';' ou a clássica vírgula. É feito assim desde os anos 80
  • se o menu_1 é o menu de cadastro e o menu_2 é o de edição porque não usa esses nomes? E para que uma interface_menu() só para escolher isso, depois de chamada por uma função  de 4 linhas?
  • escreva em torno dos dados. Seus dados são um cadastro de alunos. 
     
    char login[101];
    char nome[101];
    char matricula[13];
    char DDD[3];
    char telefone[10];
    char cpf[13];
    char idade[3];

 

Só que isso está oculto dentro de menu_1(). E tudo separado.

 

int menu_2()
{
 char login;
    printf("por favor digite o seu login\n");
    scanf("%c", &login);
    scanf("%c", &login);

 

login é char[101]; Está logo acima.

 

 scanf() está lendo uma única letra, e duas vezes no mesmo endereço. E nem está testando o retorno. Como sabe se leu a letra? Para que ler duas vezes? Vai ficar só com a segunda letra do nome e o resto vai ficar para ser lido depois...

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 comunidades 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

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!