paulo1205
(usa Ubuntu)
Enviado em 20/07/2019 - 17:59h
Outros comentários sobre o programa que podem ser úteis.
Matheus10772 escreveu:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main() {
A declaração de
main está errada. De acordo com o padrão do C, o tipo de retorno tem de ser
int , e a lista de argumentos não deve estar vazia, mas deve conter ou apenas a palavra-chave
void , para indicar que o ambiente de execução não vai passar argumentos ao programa, ou, se o programa receber argumentos do ambiente de execução, exatamente dois parâmetros, sendo o primeiro deles do tipo
int , para representar a quantidade de argumentos, e o segundo do tipo
char ** (ponteiro para ponteiro de caracteres), indicando um vetor de
strings , onde cada
string contém o texto de cada um dos argumentos passados ao programa (convencionalmente, esses parâmetros são chamados de
argc e
argv , abreviando, respectivamente,“
argument counting ” e “
argument vector ”, mas você pode usar outros nomes, desde que respeite os tipos e o sentido).
char arqnome[30];
printf("\nDigite o nome da lista de compras\n");
scanf("%s", arqnome);
Como você tem um tamanho fixo para o vetor que vai receber o nome, seria prudente limitar a quantidade de caracteres que
scanf () vai aceitar receber (por exemplo, fazendo
scanf("%29s", arqnome) ).
Além disso, a prudência recomenda também que você verifique se a leitura foi bem sucedida, antes de tentar usar o valor armazenado no destino das operações de leitura.
FILE *arq = fopen(arqnome, "r");
if (arq == NULL) { printf("\nErro ao abrir o arquivo\n"); exit(1); }
Convencionalmente, a sinalização de erros deveria ser feita numa saída separada da saída normal do programa. O usual seria você fazer da seguinte forma.
fprintf(stderr, "\nErro ao abrir o arquivo.\n");
Existe uma função específica para imprimir mensagens de erro em situações semelhantes à de abortar o programa, que indica a causa do erro, se ela for conhecida.
perror("Erro ao abrir o arquivo"); // Vai imprimir algo na forma “Erro ao abrir o arquivo: arquivo ou diretório não encontrado\n".
Erro comum, mas ainda assim erro: como você vai usar
c como destino do resultado de
fgetc (), o tipo dessa variável deveria ser
int . Do jeito como você fez, você torna a sinalização de erro indistinguível do caráter que porventura tenha o valor correspondente a
255 . Além disso, em muitas máquinas (incluindo os nossos PCs, quer rodem Linux, quer Windows), o tipo
char representa bytes na faixa que vai de
-128 a
127 , em vez de
0 a
255 , e isso pode causar problemas com funções que tratam caracteres e esperam que eles não sejam negativos (por exemplo: as funções de <ctype.h>).
while (!feof(arq))
{
c = fgetc(arq);
if (c == '\n') { count++; }
}
Você não precisa chamar explicitamente
feof (). O jeito mais usual de fazer esse laço de repetição seria o seguinte.
int c; // Note o tipo usado na declaração.
while((c=fgetc(arq))!=EOF)
if(c=='\n')
++count;
bb
char *nomeproduto = (char*)malloc(count * sizeof(char));
int *quantida = (int*)malloc(count * sizeof(int));
int *preco = (int*)malloc(count * sizeof(int));
Não é necessário, em C, converter o valor retornado por
malloc () para outro tipo de ponteiro, pois o tipo
void * é automaticamente convertido pelo compilador para qualquer outro tipo de ponteiro numa operação de atribuição. Adicionar código redundante é algo que, em geral, acaba dificultando a manutenção de código.
Adicionalmente, eu sugiro que você transfira para o compilador o trabalho de saber o tamanho de cada elemento a ser alocado, usando como argumento do operador
sizeof não o nome do tipo de cada ponteiro, mas a expressão sintática do acesso a um de seus elementos. Fazendo desse modo, a manutenção de código é facilitada, pois se você algum dia vier a alterar o tipo do ponteiro em sua declaração, não precisará de correr atrás de cada operação de alocação ou realocação e trocar os tipos também ali. Veja os exemplos abaixo, baseados no que você havia feito.
char *nomeproduto=malloc(count * sizeof nomeproduto[0]); // Aqui o compilador sabe que não se está fazendo acesso ao elemento, mas apenas calculando seu tamanho.
int *preco=malloc(count * sizeof preco[0]);
int *quantidade=malloc(count * sizeof *quantidade); // “*quantidade” é sinônimo de “quantidade[0]”.
for (int i = 0; i < count; i++) {
fscanf(arq, "%s", nomeproduto[ i]);
fscanf(arq, "%d", quantida[ i]);
fscanf(arq, "%f", preco[ i]);
Opa! Outro problema, e grave!
Você declarou
preco como ponteiro com papel de
array de dados do tipo
int , mas está usando uma conversão em
fscanf () que coloca ali um dado do tipo
float . Isso vai dar problema quando você tentar usar
preco[ i] numa expressão, pois as representações internas (olhando bit a bit) de um inteiro e de um dado de ponto flutuante são bastantes diferentes.
Aqui faltou inicializar o acumulador com zero, como já dito anteriormente.
for (int i = 0; i < count; i++) {
total = total + preco[i ];
E aqui você está usando uma variável que teve os bits tratados como se fossem os de um
float na hora da atribuição como se tais bits fossem, agora, os bits de um inteiro. A chance de dar problema é de praticamente 100%.
}
printf("\nA soma dos preocos dos produtos eh %d", total);
system("pause");
Para que esse “
system("pause") ”? Isso faz com que o programa fique estritamente dependente do sistema que você usou na sua máquina, e não possa ser rodado de modo limpo numa máquina em que o comando “pause” não seja reconhecido pelo sistema operacional.
Se o que você quer é simplesmente impedir que a janela em que o programa executa seja fechada antes que você possa ver o resultado da execução do programa, uma abordagem melhor (se o seu ambiente de desenvolvimento permitir) é verificar se existe uma opção para que a referida janela seja mantida aberta até que você deliberadamente mande fechá-la. Muitos ambientes de desenvolvimento oferecem uma opção nesse sentido.
}
o programa está retornando um valor absurdo, muito maior que a soma verdadeira.
Então isso pode ser por duas causas: tipo errado na hora de atribuir dados e falta da inicialização do acumulador.
... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)