Jump to content

Menu de opções


Ana Silva

Recommended Posts

thoga31
14 horas atrás, Ana Silva disse:

Aí como faço em memoria (da mesma forma que os animais)?

Sim.  Podes usar um novo vetor para registar as despesas, em que cada elemento é uma struct com os dados relativos a cada transação.

Cumprimentos.

Knowledge is free!

Link to post
Share on other sites
Ana Silva
Em 02/02/2021 às 13:51, thoga31 disse:

Sim.  Podes usar um novo vetor para registar as despesas, em que cada elemento é uma struct com os dados relativos a cada transação.

Cumprimentos.

Ajudem-me coloquei esta função e não está a funcionar do jeito que eu queria podem descobrir o erro?

Queria que o codigo dentro do for se repetisse ate chegar ao numero de despesas no entanto ele para a meio.

O código é o seguinte:

void inserirDespesa(){
    int numero;
    int dia;
    int mes;
    int ano;
    int i;
    printf("Qual o numero de despesas que deseja introduzir: ");
            scanf("%d", &numero);
  printf("Despesas:\n");
    for(int n = 1; n<=numero; n++){
    for(int i = 0; i<numero; i++){
         printf("%da despesa:",n);
         printf("\nData:");
         scanf("%d%d%d", &dia, &mes, &ano);
         n++;
         if ((dia >= 01 && dia <= 30) && (mes == 04 || mes == 06 || mes == 9 || mes == 11)){
     }
         if (dia >= 01 && dia <= 31 && (mes == 01 || mes == 03 || mes == 05 || mes == 07 || mes == 8|| mes == 10 || mes == 12) && ano >= 1583){
     }
       if (dia == 29 && mes == 2 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0))){
     }
     if ((dia >= 01 && dia <= 28) && (mes == 2)){
     }
         if (dia <= 00 || dia > 31){
             printf("dia invalido\n");
     }
       if (mes <= 00 || mes > 12){
             printf("mes invalido\n");
     }
       if (ano < 1583){
             printf("ano invalido\n");
     }
     consultarAnimal();
     for (i = 1; i< n_animais; i++){
     printf("\nCodigo do animal:");
     scanf("%d", &i);
     if (i > n_animais){
         printf("codigo inexistente");
     }
     }
     printf("Valor em euros:");
     scanf("%2lf",&valor);
     if (valor <= 0){
         printf("valor invalido");
     }
     printf("Descricao:");
     scanf("%s", descricao);
            }
}

 

Edited by thoga31
GeSHi
Link to post
Share on other sites
thoga31

Vou inserir em comentário ao teu código os meus apontamentos:

void inserirDespesa(){
  int numero;
  int dia;
  int mes;
  int ano;
  int i;
  
  printf("Qual o numero de despesas que deseja introduzir: ");
  scanf("%d", &numero);
  
  printf("Despesas:\n");
  for(int n = 1; n<=numero; n++) {
    for(int i = 0; i<numero; i++) {         // Para que serve este segundo ciclo for dentro do primeiro?
      printf("%da despesa:",n);
      printf("\nData:");
      scanf("%d%d%d", &dia, &mes, &ano);    // Em que formato deve o utilizador inserir a data?
      n++;
      
      // Para que servem estes 4 ifs sem qualquer conteúdo?
      if ((dia >= 01 && dia <= 30) && (mes == 04 || mes == 06 || mes == 9 || mes == 11)){
      }
      if (dia >= 01 && dia <= 31 && (mes == 01 || mes == 03 || mes == 05 || mes == 07 || mes == 8|| mes == 10 || mes == 12) && ano >= 1583){
      }
      if (dia == 29 && mes == 2 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0))){
      }
      if ((dia >= 01 && dia <= 28) && (mes == 2)){
      }
      
      // Nestes casos mostras as mensagens, mas nada impede de a operação prosseguir com estes dados errados.
      if (dia <= 00 || dia > 31){
        printf("dia invalido\n");
      }
      if (mes <= 00 || mes > 12){
        printf("mes invalido\n");
      }
      if (ano < 1583){
        printf("ano invalido\n");
      }
      
      consultarAnimal();                    // Qual animal é para consultar?
      
      for (i = 1; i< n_animais; i++){       // Este ciclo for serve que propósito?
        printf("\nCodigo do animal:");
        scanf("%d", &i);
        if (i > n_animais){
          printf("codigo inexistente");
        }
      }
      
      printf("Valor em euros:");
      scanf("%2lf",&valor);
      if (valor <= 0){   // Mais uma vez, mostras a mensagem, mas nada impede a operação de prosseguir com um valor errado.
                         // Além disso, se é um double, recomenda-se usar 0.0 (double) em vez de 0 (int).
        printf("valor invalido");
      }
      printf("Descricao:");
      scanf("%s", descricao);
    }
  }   // Faltava-te aqui uma chaveta (a não ser que não tenhas copiado a última por engano)
}

Cumprimentos.

Knowledge is free!

Link to post
Share on other sites
Ana Silva
6 minutos atrás, thoga31 disse:

Vou inserir em comentário ao teu código os meus apontamentos:


void inserirDespesa(){
  int numero;
  int dia;
  int mes;
  int ano;
  int i;
  
  printf("Qual o numero de despesas que deseja introduzir: ");
  scanf("%d", &numero);
  
  printf("Despesas:\n");
  for(int n = 1; n<=numero; n++) {
    for(int i = 0; i<numero; i++) {         // Para que serve este segundo ciclo for dentro do primeiro?
      printf("%da despesa:",n);
      printf("\nData:");
      scanf("%d%d%d", &dia, &mes, &ano);    // Em que formato deve o utilizador inserir a data?
      n++;
      
      // Para que servem estes 4 ifs sem qualquer conteúdo?
      if ((dia >= 01 && dia <= 30) && (mes == 04 || mes == 06 || mes == 9 || mes == 11)){
      }
      if (dia >= 01 && dia <= 31 && (mes == 01 || mes == 03 || mes == 05 || mes == 07 || mes == 8|| mes == 10 || mes == 12) && ano >= 1583){
      }
      if (dia == 29 && mes == 2 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0))){
      }
      if ((dia >= 01 && dia <= 28) && (mes == 2)){
      }
      
      // Nestes casos mostras as mensagens, mas nada impede de a operação prosseguir com estes dados errados.
      if (dia <= 00 || dia > 31){
        printf("dia invalido\n");
      }
      if (mes <= 00 || mes > 12){
        printf("mes invalido\n");
      }
      if (ano < 1583){
        printf("ano invalido\n");
      }
      
      consultarAnimal();                    // Qual animal é para consultar?
      
      for (i = 1; i< n_animais; i++){       // Este ciclo for serve que propósito?
        printf("\nCodigo do animal:");
        scanf("%d", &i);
        if (i > n_animais){
          printf("codigo inexistente");
        }
      }
      
      printf("Valor em euros:");
      scanf("%2lf",&valor);
      if (valor <= 0){   // Mais uma vez, mostras a mensagem, mas nada impede a operação de prosseguir com um valor errado.
                         // Além disso, se é um double, recomenda-se usar 0.0 (double) em vez de 0 (int).
        printf("valor invalido");
      }
      printf("Descricao:");
      scanf("%s", descricao);
    }
  }   // Faltava-te aqui uma chaveta (a não ser que não tenhas copiado a última por engano)
}

Cumprimentos.

Eu na parte dos for guiei-e pela outra funçao que funcionou na perfeiçao: inserir Animal(); 

Os if sem conteudo foi para nao repetir a funçao do consultarAnimal(); dai ter posto a função depois 

Só nao entendo porque ao verificar a data ela nao vai aparecer invalida mesmo tendo verificado? 

Essa parte não me deu mal no codigo e testei com diferentes datas

O formato da data dei liberdade para o utilizador pôr por exemplo: 05 02 2021 mas poderei mudar

E o consultarAnimal(); é uma função que irá mostrar os animais todos inseridos até ao momento

Antes de mais obrigada pelo auxilio

 

Link to post
Share on other sites
thoga31
6 minutos atrás, Ana Silva disse:

Eu na parte dos for guiei-e pela outra funçao que funcionou na perfeiçao: inserir Animal();

Porquê dois ciclos for encadeados? Basta um.

7 minutos atrás, Ana Silva disse:

Os if sem conteudo foi para nao repetir a funçao do consultarAnimal(); dai ter posto a função depois

O programa vai executar na mesma o código que se segue uma vez que não está dentro de elses. O facto de entrar num if não significa que vai parar ali.

8 minutos atrás, Ana Silva disse:

Só nao entendo porque ao verificar a data ela nao vai aparecer invalida mesmo tendo verificado?

Isto vem em sequência do ponto anterior. Com o if apenas mostras uma mensagem, mas não impedes explicitamente a operação de continuar! O código que vem depois do if é executado, quer a condição seja verdadeira quer não.

E estes três pontos levam-me a levantar esta questão: como achas que funcionam as estruturas for e if?
Qual achas que é o output do seguinte programa?

#include <stdio.h>

void foo(void) {
  int x = 5;
  if (x == 5) {
    printf("Cinco!\n");
  }
  printf("Não cinco!\n");
}

int main(void) {
  foo();
  return 0;
}

 

10 minutos atrás, Ana Silva disse:

O formato da data dei liberdade para o utilizador pôr por exemplo: 05 02 2021 mas poderei mudar

Apenas perguntei porque colocaste os %d todos seguidos, sem espaços entre eles. Se o utilizador deve inserir a data entre espaços, recomendo também indicares os espaços de forma explícita no scanf() (ou seja, scanf("%d %d %d", ...)).

12 minutos atrás, Ana Silva disse:

E o consultarAnimal(); é uma função que irá mostrar os animais todos inseridos até ao momento

Vais mostrar todos os animais depois de cada despesa inserida? Não será muita informação por cada iteração?

 

Cumprimentos.

 

Knowledge is free!

Link to post
Share on other sites
Ana Silva
17 horas atrás, thoga31 disse:

Porquê dois ciclos for encadeados? Basta um.

O programa vai executar na mesma o código que se segue uma vez que não está dentro de elses. O facto de entrar num if não significa que vai parar ali.

Isto vem em sequência do ponto anterior. Com o if apenas mostras uma mensagem, mas não impedes explicitamente a operação de continuar! O código que vem depois do if é executado, quer a condição seja verdadeira quer não.

E estes três pontos levam-me a levantar esta questão: como achas que funcionam as estruturas for e if?
Qual achas que é o output do seguinte programa?


#include <stdio.h>

void foo(void) {
  int x = 5;
  if (x == 5) {
    printf("Cinco!\n");
  }
  printf("Não cinco!\n");
}

int main(void) {
  foo();
  return 0;
}

 

Apenas perguntei porque colocaste os %d todos seguidos, sem espaços entre eles. Se o utilizador deve inserir a data entre espaços, recomendo também indicares os espaços de forma explícita no scanf() (ou seja, scanf("%d %d %d", ...)).

Vais mostrar todos os animais depois de cada despesa inserida? Não será muita informação por cada iteração?

 

Cumprimentos.

 

Isso tem a ver porque antes do nome do animal tenho de por o numero dai os dois ciclos um para contar o n_animais e outro o i que sera a ordem {1,2,3...}

Mas ele no terminal funcionou como eu queria por isso penso que não seja esse o problema

Entao nessa situação devo usar o if else para nao repetir a instruçao seguinte?

Nesse caso acho que o output será os dois printf's devido a nao ter o else certo?

Já alterei essa parte

Sim, afim da pessoa escolher o animal dentro daqueles que ja existem

Link to post
Share on other sites
thoga31
9 horas atrás, Ana Silva disse:

Entao nessa situação devo usar o if else para nao repetir a instruçao seguinte?

Nesse caso acho que o output será os dois printf's devido a nao ter o else certo?

Certo. Portanto, a tua primeira questão responde-se com a tua resposta à segunda questão. Se não tens um else ou uma outra forma de impedir que o programa de facto não execute operações com valores inválidos, então ele faz as operações.

Portanto, estes ifs não vão fazer absolutamente nada:

if ((dia >= 01 && dia <= 30) && (mes == 04 || mes == 06 || mes == 9 || mes == 11)){
}
if (dia >= 01 && dia <= 31 && (mes == 01 || mes == 03 || mes == 05 || mes == 07 || mes == 8|| mes == 10 || mes == 12) && ano >= 1583){
}
if (dia == 29 && mes == 2 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0))){
}
if ((dia >= 01 && dia <= 28) && (mes == 2)){
}

Caso as condições se verifiquem, o programa entra dentro de cada if (por ordem), não faz nada (pois o conteúdo é oco) e continua a executar o resto da iteração do ciclo for.

Algo semelhante acontece aqui:

if (dia <= 00 || dia > 31){
  printf("dia invalido\n");
}
if (mes <= 00 || mes > 12){
  printf("mes invalido\n");
}
if (ano < 1583){
  printf("ano invalido\n");
}

Parece-te que está certo porque recebes o feedback com o output das mensagens, mas o programa vai continuar a executar na mesma porque a única coisa que fizeste com os dados inválidos foi dizer que são inválidos! Onde indicas expressamente ao programa que não deve avançar com estes dados inválidos? Hint: não indicas.

 

Quanto às restantes questões, que se prendem com os ciclos for, tens 3 ciclos encadeados. Vamos analisar.

1. Primeiro perguntas ao utilizador quantas despesas quer adicionar.

printf("Qual o numero de despesas que deseja introduzir: ");
scanf("%d", &numero);

2.1. Para o número de despesas que o utilizador pediu (n de 1 até numero)...

for (int n = 1; n <= numero; n++) {

2.2. ... e para o número de despesas outra vez (i de 0 a numero-1)...

for (int i = 0; i < numero; i++) {

Ou seja, neste ponto, se o utilizador indicar que quer inserir 3 despesas, vão ocorrer 9 iterações. Ou seja, irão decorrer numero² iterações. Era isto que pretendias?

3. Depois, dentro destes dois ciclos, tens um terceiro encadeado, que diz: "Para cada animal (i de 1 até n_animais-1)..."

for (i = 1; i < n_animais; i++) {
  printf("\nCodigo do animal:");
  scanf("%d", &i);
  if (i > n_animais){
    printf("codigo inexistente");
  }
}

Se tiveres 20 animais, vais perguntar 19 vezes pelo código do animal. Era isto que pretendias?
Além de que estás a usar a própria variável i, utilizada para controlar o ciclo, para obter input do utilizador!

Por fim...

9 horas atrás, Ana Silva disse:

Sim, afim da pessoa escolher o animal dentro daqueles que ja existem

Estás a chamar a função consultarAnimal() dentro do segundo ciclo for! Vejamos onde está a função retirando o restante código...

void inserirDespesa(){
  // ...
  for(int n = 1; n<=numero; n++) {          // 1° ciclo
    for(int i = 0; i<numero; i++) {         // 2° ciclo, encadeado dentro do 1°
      // ...
      
      consultarAnimal();                    // <-- Aqui está ela!
      
      for (i = 1; i< n_animais; i++){       // 3° ciclo, encadeado dentro do 2°, o qual está encadeado dentro do 1°
        // ...
      }
      // ...
    }
  }
}

Ora, se o utilizador inserir 3 para a variável numero, vais mostrar 9 vezes a lista de animais (conforme o supra-citad). Era isto que pretendias?

 

Sugiro voltar um passo atrás para percebermos o que realmente queres que a função faça.
Diz-me qual o objectivo da função inserirDespesa() e indica-me o respectivo pseudocódigo.

 

Por fim, em estilo de sidenote...

9 horas atrás, Ana Silva disse:

Mas ele no terminal funcionou como eu queria por isso penso que não seja esse o problema

O facto de aparentemente funcionar como querias não significa que não haja um problema ou um bug no respectivo código.
Neste caso, basta indicares que só queres fazer 1 despesa e o código vai (em boa parte) aparentar funcionar.

 

Cumprimentos.

Edited by thoga31

Knowledge is free!

Link to post
Share on other sites
Ana Silva
22 horas atrás, thoga31 disse:

Certo. Portanto, a tua primeira questão responde-se com a tua resposta à segunda questão. Se não tens um else ou uma outra forma de impedir que o programa de facto não execute operações com valores inválidos, então ele faz as operações.

Portanto, estes ifs não vão fazer absolutamente nada:






if ((dia >= 01 && dia <= 30) && (mes == 04 || mes == 06 || mes == 9 || mes == 11)){
}
if (dia >= 01 && dia <= 31 && (mes == 01 || mes == 03 || mes == 05 || mes == 07 || mes == 8|| mes == 10 || mes == 12) && ano >= 1583){
}
if (dia == 29 && mes == 2 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0))){
}
if ((dia >= 01 && dia <= 28) && (mes == 2)){
}

Caso as condições se verifiquem, o programa entra dentro de cada if (por ordem), não faz nada (pois o conteúdo é oco) e continua a executar o resto da iteração do ciclo for.

Algo semelhante acontece aqui:






if (dia <= 00 || dia > 31){
  printf("dia invalido\n");
}
if (mes <= 00 || mes > 12){
  printf("mes invalido\n");
}
if (ano < 1583){
  printf("ano invalido\n");
}

Parece-te que está certo porque recebes o feedback com o output das mensagens, mas o programa vai continuar a executar na mesma porque a única coisa que fizeste com os dados inválidos foi dizer que são inválidos! Onde indicas expressamente ao programa que não deve avançar com estes dados inválidos? Hint: não indicas.

 

Quanto às restantes questões, que se prendem com os ciclos for, tens 3 ciclos encadeados. Vamos analisar.

1. Primeiro perguntas ao utilizador quantas despesas quer adicionar.






printf("Qual o numero de despesas que deseja introduzir: ");
scanf("%d", &numero);

2.1. Para o número de despesas que o utilizador pediu (n de 1 até numero)...






for (int n = 1; n <= numero; n++) {

2.2. ... e para o número de despesas outra vez (i de 0 a numero-1)...






for (int i = 0; i < numero; i++) {

Ou seja, neste ponto, se o utilizador indicar que quer inserir 3 despesas, vão ocorrer 9 iterações. Ou seja, irão decorrer numero² iterações. Era isto que pretendias?

3. Depois, dentro destes dois ciclos, tens um terceiro encadeado, que diz: "Para cada animal (i de 1 até n_animais-1)..."






for (i = 1; i < n_animais; i++) {
  printf("\nCodigo do animal:");
  scanf("%d", &i);
  if (i > n_animais){
    printf("codigo inexistente");
  }
}

Se tiveres 20 animais, vais perguntar 19 vezes pelo código do animal. Era isto que pretendias?
Além de que estás a usar a própria variável i, utilizada para controlar o ciclo, para obter input do utilizador!

Por fim...

Estás a chamar a função consultarAnimal() dentro do segundo ciclo for! Vejamos onde está a função retirando o restante código...






void inserirDespesa(){
  // ...
  for(int n = 1; n<=numero; n++) {          // 1° ciclo
    for(int i = 0; i<numero; i++) {         // 2° ciclo, encadeado dentro do 1°
      // ...
      
      consultarAnimal();                    // <-- Aqui está ela!
      
      for (i = 1; i< n_animais; i++){       // 3° ciclo, encadeado dentro do 2°, o qual está encadeado dentro do 1°
        // ...
      }
      // ...
    }
  }
}

Ora, se o utilizador inserir 3 para a variável numero, vais mostrar 9 vezes a lista de animais (conforme o supra-citad). Era isto que pretendias?

 

Sugiro voltar um passo atrás para percebermos o que realmente queres que a função faça.
Diz-me qual o objectivo da função inserirDespesa() e indica-me o respectivo pseudocódigo.

 

Por fim, em estilo de sidenote...

O facto de aparentemente funcionar como querias não significa que não haja um problema ou um bug no respectivo código.
Neste caso, basta indicares que só queres fazer 1 despesa e o código vai (em boa parte) aparentar funcionar.

 

Cumprimentos.

Muito obrigada pela explicação detalhada, ja corrigi!

Já consegui inserir mais que uma categoria!

Agora o ultimo passo é passar esses dados como uma consulta para ficheiro txt onde tem os meses, o ano e o valor gasto.

Eu fiz desse jeito:

void consultarDespesa(){
  printf("Qual ano deseja? (aaaa):");
  scanf("%d",&ano);
  printf("entre com o nome do ficheiro: ");
  scanf("%s", ficheiro);
  printf("\n");
  dados=fopen(ficheiro, "a");

  fprintf(dados, "\nano (aaaa): %d\nMes     Valor\n", ano);
  fprintf(dados, "%d       %.2f",mes,valor);
  fclose(dados);
}

Mas só me está a aparecer o ultimo mes que ponho alguma recomendação?

Edited by thoga31
GeSHi
Link to post
Share on other sites
thoga31

De onde vêm essas variáveis ano, mes e valor?
Esse código só vai escrever uma vez no ficheiro. Suponho que estejas a chamar a função de outra função dentro de um ciclo for.

O problema ou está no local onde chamas essa função (não estás a iterar várias vezes sobre dados diferentes), ou está nessa função se a tua ideia é escrever uma série de dados de uma vez só aí mesmo.

Knowledge is free!

Link to post
Share on other sites
Ana Silva
Em 07/02/2021 às 23:43, thoga31 disse:

De onde vêm essas variáveis ano, mes e valor?
Esse código só vai escrever uma vez no ficheiro. Suponho que estejas a chamar a função de outra função dentro de um ciclo for.

O problema ou está no local onde chamas essa função (não estás a iterar várias vezes sobre dados diferentes), ou está nessa função se a tua ideia é escrever uma série de dados de uma vez só aí mesmo.

Como assim de onde vêm ? Elas fazem parte das despesas são etapas que são usadas para utilizar as despesas

Eu fiz de uma forma que já funcionou só que em relação ao ano mes e valor eu queria poder filtrar um ano á escolha em que o utilizador pudesse ver as suas despesas somente desse ano alguma sugestao? Eu fiz assim de forma a escrever os dados num ficheiro mas o ano nao está a funcionar como pretendido:

Essa é a função que eu fiz:

void consultarDespesa(){
  printf("Qual ano deseja? (aaaa):");
  scanf("%d",&ano);
  printf("entre com o nome do ficheiro: ");
  scanf("%s", ficheiro);
  printf("\n");
  dados=fopen(ficheiro, "r");
  printf("\nano (aaaa): %d\nMes     Valor\n", ano);
  while((info=fgetc(dados)) != EOF ){
    if(info!='\n'){
      printf("%c", info);
    }
    else
      printf("\n");
  }
  fclose(dados);
}

 

Uma outra duvida é como eu abro o ficheiro sem perguntar o seu nome ao utilizador?

Obrigada

Edited by thoga31
GeSHi
Link to post
Share on other sites
thoga31
9 horas atrás, Ana Silva disse:

Como assim de onde vêm ?

Não sei onde declaraste as variáveis.

9 horas atrás, Ana Silva disse:

eu queria poder filtrar um ano á escolha em que o utilizador pudesse ver as suas despesas somente desse ano alguma sugestao?

Depende de como estás a guardar as informações no ficheiro. Dá-me um exemplo de um ficheiro gerado pelo programa.

9 horas atrás, Ana Silva disse:

 


while((info=fgetc(dados)) != EOF ){
  if(info!='\n'){
    printf("%c", info);
  }
  else
    printf("\n");
}

 

Por que motivo estás a diferenciar o \n? É um caracter como outro qualquer, e visto que não estás a fazer mais do que fazer output dos caracteres, não precisas desse if.

9 horas atrás, Ana Silva disse:

Uma outra duvida é como eu abro o ficheiro sem perguntar o seu nome ao utilizador?

FILE *f = fopen("batatas.txt", "r");

 

Cumprimentos.

Knowledge is free!

Link to post
Share on other sites
Ana Silva
Em 12/02/2021 às 20:19, thoga31 disse:

Não sei onde declaraste as variáveis.

Depende de como estás a guardar as informações no ficheiro. Dá-me um exemplo de um ficheiro gerado pelo programa.

Por que motivo estás a diferenciar o \n? É um caracter como outro qualquer, e visto que não estás a fazer mais do que fazer output dos caracteres, não precisas desse if.





FILE *f = fopen("batatas.txt", "r");

 

Cumprimentos.

Declarei como variaveis globais para poder usar sempre que quiser

O meu ficheiro estava a dar mal as informações mas o meu objetivo de exemplo de ficheiro é:

ano: 2021

mes           valor

01               279.97

02               129.13

03                 90.13

sendo que o valor será a soma de todas as despesas desse mesmo ano e mes

Preciso para poder escrever o que está no ficheiro enquanto não chegar ao '\n' ou seja o espaço

Ok obrigada essa parte já tinha chegado

Uma outra duvida: tem alguma maneira mais eficaz de mudar uma linha de um ficheiro usando o strcpy com o fgets?

 

 

Edited by Ana Silva
Link to post
Share on other sites
thoga31

Não dupliques respostas. Quando for assim, pede para vermos a tua resposta anterior: o tópico volta ao topo do quadro e não temos informação duplicada. ;)

 

Em 15/02/2021 às 16:18, Ana Silva disse:

O meu ficheiro estava a dar mal as informações mas o meu objetivo de exemplo de ficheiro é:

ano: 2021

mes           valor

01               279.97

02               129.13

03                 90.13

sendo que o valor será a soma de todas as despesas desse mesmo ano e mes

Podes usar o scanf ou uma combinação de fgets com sscanf para ler os dados de cada linha. Por exemplo:

char line[120];
int mes;
float valor;
FILE *f = fopen("batatas.txt", "r");
fgets(line, 120, f);
sscanf(line, "%d %f ", &mes, &valor);

 

Em 15/02/2021 às 16:18, Ana Silva disse:

Preciso para poder escrever o que está no ficheiro enquanto não chegar ao '\n' ou seja o espaço

Por que não fazer isto directamente?

while((info = fgetc(dados)) != EOF){
  printf("%c", info);
}

Ou então:

char line[120];
FILE *f = fopen("batatas.txt", "r");
while (!feof(f)) {
  fgets(line, 120, f);
  fputs(line, stdout);
}

 

Em 15/02/2021 às 16:18, Ana Silva disse:

tem alguma maneira mais eficaz de mudar uma linha de um ficheiro usando o strcpy com o fgets?

Recomendo a leitura deste post do Stack Overflow. Dificilmente poderei dar uma explicação mais completa.

 

Em 15/02/2021 às 16:18, Ana Silva disse:

Declarei como variaveis globais para poder usar sempre que quiser

Cuidado com o uso de variáveis globais. Se não controlares bem o fluxo do programa, poderás ter efeitos secundários os quais nem sempre são fáceis de detectar a origem.

 

Cumprimentos.

Knowledge is free!

Link to post
Share on other sites
Ana Silva
Em 17/02/2021 às 22:14, thoga31 disse:

Não dupliques respostas. Quando for assim, pede para vermos a tua resposta anterior: o tópico volta ao topo do quadro e não temos informação duplicada. ;)

 

Podes usar o scanf ou uma combinação de fgets com sscanf para ler os dados de cada linha. Por exemplo:



char line[120];
int mes;
float valor;
FILE *f = fopen("batatas.txt", "r");
fgets(line, 120, f);
sscanf(line, "%d %f ", &mes, &valor);

 

Por que não fazer isto directamente?



while((info = fgetc(dados)) != EOF){
  printf("%c", info);
}

Ou então:



char line[120];
FILE *f = fopen("batatas.txt", "r");
while (!feof(f)) {
  fgets(line, 120, f);
  fputs(line, stdout);
}

 

Recomendo a leitura deste post do Stack Overflow. Dificilmente poderei dar uma explicação mais completa.

 

Cuidado com o uso de variáveis globais. Se não controlares bem o fluxo do programa, poderás ter efeitos secundários os quais nem sempre são fáceis de detectar a origem.

 

Cumprimentos.

Peço desculpa, mandei por engano

Obrigada pela dica

Realmente nao pensei nisso 

Serio? Para já está tudo a funcionar na normalidade queria saber é como posso filtrar os dados de um ficheiro para aparecer no terminal?

Não consigo com este codigo fazer aparecer a categoria que quero:

void consultaDetalhada(){
    printf("mes (mm):");
    scanf("%d",&mesescolhido);
    printf("ano (aaaa):");
    scanf("%d",&anoescolhido);
    despesas=fopen("despesas.txt", "r");
    if(despesas == NULL){
        printf("erro ao abrir o ficheiro\n");
        return;
    }
    printf("\nmes/ano (mm/aaaa): %d/%d\n",mesescolhido, anoescolhido);
    printf("data       categoria     valor     descricao\n");
    while (fscanf(despesas, "%d-%d-%d %s %lf %s",&dia, &mes, &ano, &codigo, &valor, &descricao) != EOF){
        printf("%d-%d-%d  %s             %.2f      %s\n",dia[n_despesas], mes[n_despesas], ano[n_despesas], categoria[n_categorias], valor[n_despesas], descricao[n_despesas]);
    }
    fclose(despesas);
}

Cumprimentos

Edited by thoga31
GeSHi
Link to post
Share on other sites
thoga31

A função fscanf() não retorna o caracter lido, mas sim o número de dados lidos com sucesso. Portanto, comparar com EOF resultará em efeitos secundários não desejados. Usa antes a função feof().

Depois, se dia, mes, ano e as restantes variáveis são inteiros e floats, a utilização do operador [] não é válida pois não são vectores.

Se queres filtrar pela categoria, tens de comparar a categoria desejada com a categoria lida em cada linha e, com um if, mostrar os dados lidos se e só se a categoria for a pretendida.

O que procuras é, portanto, algo deste género (mero exemplo):

Dado o ficheiro:

01-01-2021 Alimentacao 23.56 Racao
02-01-2021 Saude 40.00 Consulta
05-01-2021 Alimentacao 12.00 Latas

Se quiseres mostrar apenas a categoria de Alimentacao, o código será algo deste género:

while (!feof(f)) {
  fgets(linha, 120, f);
  if (sscanf(linha, "%d-%d-%d %s %f %s ", &dia, &mes, &ano, &categoria, &valor, &descricao) == 6) {
    if (strcmp(categoria, "Alimentacao") == 0) {
      printf("%02d-%02d-%04d %0.2f %s\n", dia, mes, ano, valor, descricao);
    }
  }
}

Faço notar que este código não deverá funcionar como esperado caso as descrições e/ou as categorias sejam strings que incluam espaços.

Cumprimentos.

Knowledge is free!

Link to post
Share on other sites
12 horas atrás, thoga31 disse:

A função fscanf() não retorna o caracter lido, mas sim o número de dados lidos com sucesso. Portanto, comparar com EOF resultará em efeitos secundários não desejados. Usa antes a função feof().

Depois, se dia, mes, ano e as restantes variáveis são inteiros e floats, a utilização do operador [] não é válida pois não são vectores.

Se queres filtrar pela categoria, tens de comparar a categoria desejada com a categoria lida em cada linha e, com um if, mostrar os dados lidos se e só se a categoria for a pretendida.

O que procuras é, portanto, algo deste género (mero exemplo):

Dado o ficheiro:


01-01-2021 Alimentacao 23.56 Racao
02-01-2021 Saude 40.00 Consulta
05-01-2021 Alimentacao 12.00 Latas

Se quiseres mostrar apenas a categoria de Alimentacao, o código será algo deste género:


while (!feof(f)) {
  fgets(linha, 120, f);
  if (sscanf(linha, "%d-%d-%d %s %f %s ", &dia, &mes, &ano, &categoria, &valor, &descricao) == 6) {
    if (strcmp(categoria, "Alimentacao") == 0) {
      printf("%02d-%02d-%04d %0.2f %s\n", dia, mes, ano, valor, descricao);
    }
  }
}

Faço notar que este código não deverá funcionar como esperado caso as descrições e/ou as categorias sejam strings que incluam espaços.

Cumprimentos.

Muito Obrigada consegui finalizar o código! 

Link to post
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.