Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

1. Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 19/07/2019 - 00:13h

Estou aprendendo a programas em C, e preciso fazer um programa simples que abra uma lista de compras, some o preço dos produtos, e em seguida imprima o resultado da soma. Esse arquivo, possuí em cada linha, o nome do produto, a quantidade disponível, e o preço unitário.

Segue o código:

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

void main() {
char arqnome[30];
printf("\nDigite o nome da lista de compras\n");
scanf("%s", arqnome);
FILE *arq = fopen(arqnome, "r");
if (arq == NULL) { printf("\nErro ao abrir o arquivo\n"); exit(1); }
int count=0;
char c;
while (!feof(arq))
{
c = fgetc(arq);
if (c == '\n') { count++; }
}

char *nomeproduto = (char*)malloc(count * sizeof(char));
int *quantida = (int*)malloc(count * sizeof(int));
int *preco = (int*)malloc(count * sizeof(int));

for (int i = 0; i < count; i++) {
fscanf(arq, "%s", nomeproduto[i]);
fscanf(arq, "%d", quantida[i]);
fscanf(arq, "%f", preco[i]);
}
int total;
for (int i = 0; i < count; i++) {
total = total + preco[i];
}
printf("\nA soma dos preocos dos produtos eh %d", total);

system("pause");
}


o programa está retornando um valor absurdo, muito maior que a soma verdadeira.


  


2. Re: Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/07/2019 - 16:35h

Como total é uma variável automática, o valor inicial dela é desconhecido. Se você vai empregá-la para acumular os valores lidos, tem de explicitamente fazer seu valor inicial igual a zero.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


3. Re: Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

Paulo
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". 


	int count=0;
char c;


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.

	}
int total;


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)


4. Re: Problema com soma de valores armazenados em um arquivo

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 21/07/2019 - 14:00h

fiz um novo código que funcionou


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

int main(void) {
char arqnome[30];

printf("\nDigite o nome da lista de compras\n");
scanf("%29s", arqnome);
FILE *arq = fopen(arqnome, "r");

if (arq == NULL) { perror("Erro ao abrir o arquivo");

int verificar;
printf("\nprecione qualquer tecla para encerrar o programa\n");
scanf("%c", verificar);
if (isdigit(verificar) != 0 || isdigit(verificar) == 0)
{
exit(1);
}
}

int linhas = 0;
int letras = 0;
int c;

while (!feof(arq))
{
c = fgetc(arq);

if (isdigit(c) == 0 && c != '\n' && c != ' ') { letras++; }
else
{
if (c == '\n') { linhas++; }
}

}
letras--;

printf("\n%d letras", letras);
printf("\n%d linhas", linhas);

char** nomeproduto = malloc(linhas * sizeof(char));
for (int i = 0; i < linhas; i++) {
nomeproduto[i] = malloc(sizeof(char) * 10);
}

int* quantida = malloc(linhas * sizeof(int));
int* preco = malloc(linhas * sizeof(int));

for (int clean = 0; clean < linhas; clean++) { quantida[clean] = 0; preco[clean] = 0; }


fclose(arq);
FILE *arq1 = fopen(arqnome, "r");


for (int j = 0; j < linhas; j++)
{
fscanf(arq1, "%s", nomeproduto[j]);
fscanf(arq1, "%d", &quantida[j]);
fscanf(arq1, "%d", &preco[j]);

}

int total = 0;
for (int k = 0; k < linhas; k++) {
total = total + (preco[k] * quantida[k]);
}

printf("\nA soma dos preocos dos produtos eh %d", total);
printf("\n");
fclose(arq1);
setbuf(stdin, NULL);
printf("\nprecione qualquer tecla para encerrar o programa\n");
int verificar;
scanf("%c", verificar);
if (isdigit(verificar)!=0 || isdigit(verificar)==0)
{
exit(1);
}
}


minha dúvida é como fazer a verificação do scanf.

Outra observação: o comando perror("Erro ao abrir o arquivo"); que você me sugeriu não funciona.


5. Re: Problema com soma de valores armazenados em um arquivo

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/07/2019 - 23:27h

Matheus10772 escreveu [mas não nessa ordem]:

minha dúvida é como fazer a verificação do scanf.


Eu posso mostrar†, mas eu recomendo que, antes disso, você leia a documentação da função‡ e tente entender seu funcionamento. Se você tiver dúvidas, poste aqui.

fiz um novo código que funcionou

    …

Outra observação: o comando perror("Erro ao abrir o arquivo"); que você me sugeriu não funciona.


Dado que o program inclui o uso de perror(), acho que uma das afirmações contradiz a outra.

Você pode explicar melhor o que é esse “não funciona”? Não compila? Dá erro de execução? Imprime lixo? Imprime texto em outra língua? Alguma outra coisa?

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

int main(void) {
char arqnome[30];

printf("\nDigite o nome da lista de compras\n");
scanf("%29s", arqnome);
FILE *arq = fopen(arqnome, "r");

if (arq == NULL) { perror("Erro ao abrir o arquivo");

int verificar;
printf("\nprecione qualquer tecla para encerrar o programa\n");
scanf("%c", verificar);


Não entendo muito essa ideia de querer que o usuário pressione (com “ss”, não com “c”) uma tecla para sair de um programa, se já não há mais nada para executar (o que é diferente de perguntar se o usuário quer continuar rodando o programa para efetuar mais uma operação, o que é perfeitamente válido).

Se for apenas para impedir que a janela na qual o programa possa estar executando se feche, (condição que é externa ao programa, e pode variar ao longo do tempo), então seria mais adequado configurar quem quer que tenha aberto a janela em que o programa roda para que a mantenha aberta por um tempo suficiente para que você possa ver o resultado, ou até que você explicitamente mande fechá-la. Isso é geralmente possível de fazer nos ambientes de desenvolvimento integrados (Code::Blocks, Dev-C++, Visual Studio etc.), bem como no próprio ambiente gráfico (tanto no Windows quando no Gnome ou KDE, comuns no Linux).

	if (isdigit(verificar) != 0 || isdigit(verificar) == 0) 


Esse teste não faz sentido, pois será sempre verdadeiro (você testa tanto uma condição quanto o seu oposto, e faz o ou lógico das duas, de modo que sempre exatamente uma delas será verdadeira, e portanto o ou lógico também). Para que tal teste, então?

	{
exit(1);
}
}

int linhas = 0;
int letras = 0;
int c;

while (!feof(arq))
{
c = fgetc(arq);

if (isdigit(c) == 0 && c != '\n' && c != ' ') { letras++; }
else
{
if (c == '\n') { linhas++; }
}


Os testes acima estão errados. Existem outras categorias de caracteres, além de dígitos e de dois casos particulares de espaços em branco: há outros espaços em branco, caracteres de controle, caracteres de pontuação, caracteres não-imprimíveis etc.

Seria mais preciso se você tivesse feito do seguinte modo.
if(isalpha(c))
++letras;
else if(c=='\n')
++linhas;



}
letras--;


Creio que o motivo desse deremento é o fato de você ter recebido o valor EOF na variável c antes de ter feof(arq) retornando um valor verdadeiro, para encerrar o laço de repetição. Isso reforça minha recomendação anterior de não basear o laço em feof(), mas no próprio valor retornado por fgetc(), que é a forma usual que você verá outros programadores em C usar.


printf("\n%d letras", letras);
printf("\n%d linhas", linhas);

char** nomeproduto = malloc(linhas * sizeof(char));


Isso está errado, pois sizeof(char) não corresponde ao dado apontado pelo ponteiro. Você possivelmente quis dizer “sizeof(char *)”.

Eis um erro bobo que reforça minha recomendação de não usar nomes de tipos com sizeof, mas sim a própria forma de designação de um dos elementos que estão sendo alocados (no caso acima, seria “sizeof(nomeproduto[0])” ou “sizeof *nomeproduto”).

A mesma recomendação se aplica a todas as alocações feitas abaixo — e a qualquer outra alocação que você faça ao longo da vida.

	for (int i = 0; i < linhas; i++) {
nomeproduto[i] = malloc(sizeof(char) * 10);
}

int* quantida = malloc(linhas * sizeof(int));
int* preco = malloc(linhas * sizeof(int));

for (int clean = 0; clean < linhas; clean++) { quantida[clean] = 0; preco[clean] = 0; }


Você não precisa zerar esses elementos, pois mais abaixo vai sobrescrever seus valores.

Contudo, se você quiser zerar todos os elementos, desde o momento da alocação dinâmica, pode usar calloc() em lugar de malloc().



fclose(arq);
FILE *arq1 = fopen(arqnome, "r");


for (int j = 0; j < linhas; j++)
{
fscanf(arq1, "%s", nomeproduto[j]);
fscanf(arq1, "%d", &quantida[j]);
fscanf(arq1, "%d", &preco[j]);

}

int total = 0;
for (int k = 0; k < linhas; k++) {
total = total + (preco[k] * quantida[k]);


A maneira mais usual de expressar isso em C seria “total += preco[k]*quantida[k];”. E você não precisaria de ter esperado até aqui para calcular isso: como o preço e a quantidade de cada produto dependem só de si mesmos, e não de outros produtos, você já poderia ter acumulado esse total no mesmo laço de repetição em que faz a leitura, após ler todos os campos de cada registro.

	}

printf("\nA soma dos preocos dos produtos eh %d", total);
printf("\n");
fclose(arq1);
setbuf(stdin, NULL);


Esse uso de setbuf() é errado, violando um restrição expressa da função setbuf(), de acordo com o padrão do C (§7.21.5.6, parágrafo 2, do padrão do C de 2018), que diz que setvbuf() (que é a função chamada internamente por setbuf(), de acordo com a §7.21.5.5 do mesmo padrão) só pode ser invocada sobre um stream que tenha acabado se ser aberto e que ainda não tenha sofrido nenhuma operação de entrada ou de saída. Não é o caso de stdin no seu programa.

Se sua preocupação e intenção é retirar do buffer de entrada caracteres que não lhe interessam, a maneira correta de fazer é ler tais caracteres, certificar-se de que realmente não lhe interessam, e então descartá-los.

	printf("\nprecione qualquer tecla para encerrar o programa\n");
int verificar;
scanf("%c", verificar);
if (isdigit(verificar)!=0 || isdigit(verificar)==0)
{
exit(1);
}
}


------------
† Isso já foi discutido à exaustão aqui no fórum da comunidade. Se você fizer uma busca, logo encontrará.

‡ Entre outras possíveis fontes, a documentação de scanf() que acompanha as bibliotecas de desenvolvimento do Linux é muito boa. Se você usar Linux, pode ler sobre a função no terminal, através do comando “man scanf”. Caso não use Linux ou não possua a documentação instalada, pode consultar on-line, em https://linux.die.net/man/3/scanf. No padrão do C de 2018, a função é descrita na §7.21.5.2.

... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


6. Re: Problema com soma de valores armazenados em um arquivo

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 23/07/2019 - 14:04h

paulo1205 escreveu:

Matheus10772 escreveu [mas não nessa ordem]:

minha dúvida é como fazer a verificação do scanf.


Eu posso mostrar†, mas eu recomendo que, antes disso, você leia a documentação da função‡ e tente entender seu funcionamento. Se você tiver dúvidas, poste aqui.

fiz um novo código que funcionou

    …

Outra observação: o comando perror("Erro ao abrir o arquivo"); que você me sugeriu não funciona.


Dado que o program inclui o uso de perror(), acho que uma das afirmações contradiz a outra.

Você pode explicar melhor o que é esse “não funciona”? Não compila? Dá erro de execução? Imprime lixo? Imprime texto em outra língua? Alguma outra coisa?

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

int main(void) {
char arqnome[30];

printf("\nDigite o nome da lista de compras\n");
scanf("%29s", arqnome);
FILE *arq = fopen(arqnome, "r");

if (arq == NULL) { perror("Erro ao abrir o arquivo");

int verificar;
printf("\nprecione qualquer tecla para encerrar o programa\n");
scanf("%c", verificar);


Não entendo muito essa ideia de querer que o usuário pressione (com “ss”, não com “c”) uma tecla para sair de um programa, se já não há mais nada para executar (o que é diferente de perguntar se o usuário quer continuar rodando o programa para efetuar mais uma operação, o que é perfeitamente válido).

Se for apenas para impedir que a janela na qual o programa possa estar executando se feche, (condição que é externa ao programa, e pode variar ao longo do tempo), então seria mais adequado configurar quem quer que tenha aberto a janela em que o programa roda para que a mantenha aberta por um tempo suficiente para que você possa ver o resultado, ou até que você explicitamente mande fechá-la. Isso é geralmente possível de fazer nos ambientes de desenvolvimento integrados (Code::Blocks, Dev-C++, Visual Studio etc.), bem como no próprio ambiente gráfico (tanto no Windows quando no Gnome ou KDE, comuns no Linux).

	if (isdigit(verificar) != 0 || isdigit(verificar) == 0) 


Esse teste não faz sentido, pois será sempre verdadeiro (você testa tanto uma condição quanto o seu oposto, e faz o ou lógico das duas, de modo que sempre exatamente uma delas será verdadeira, e portanto o ou lógico também). Para que tal teste, então?

	{
exit(1);
}
}

int linhas = 0;
int letras = 0;
int c;

while (!feof(arq))
{
c = fgetc(arq);

if (isdigit(c) == 0 && c != '\n' && c != ' ') { letras++; }
else
{
if (c == '\n') { linhas++; }
}


Os testes acima estão errados. Existem outras categorias de caracteres, além de dígitos e de dois casos particulares de espaços em branco: há outros espaços em branco, caracteres de controle, caracteres de pontuação, caracteres não-imprimíveis etc.

Seria mais preciso se você tivesse feito do seguinte modo.
if(isalpha(c))
++letras;
else if(c=='\n')
++linhas;



}
letras--;


Creio que o motivo desse deremento é o fato de você ter recebido o valor EOF na variável c antes de ter feof(arq) retornando um valor verdadeiro, para encerrar o laço de repetição. Isso reforça minha recomendação anterior de não basear o laço em feof(), mas no próprio valor retornado por fgetc(), que é a forma usual que você verá outros programadores em C usar.


printf("\n%d letras", letras);
printf("\n%d linhas", linhas);

char** nomeproduto = malloc(linhas * sizeof(char));


Isso está errado, pois sizeof(char) não corresponde ao dado apontado pelo ponteiro. Você possivelmente quis dizer “sizeof(char *)”.

Eis um erro bobo que reforça minha recomendação de não usar nomes de tipos com sizeof, mas sim a própria forma de designação de um dos elementos que estão sendo alocados (no caso acima, seria “sizeof(nomeproduto[0])” ou “sizeof *nomeproduto”).

A mesma recomendação se aplica a todas as alocações feitas abaixo — e a qualquer outra alocação que você faça ao longo da vida.

	for (int i = 0; i < linhas; i++) {
nomeproduto[i] = malloc(sizeof(char) * 10);
}

int* quantida = malloc(linhas * sizeof(int));
int* preco = malloc(linhas * sizeof(int));

for (int clean = 0; clean < linhas; clean++) { quantida[clean] = 0; preco[clean] = 0; }


Você não precisa zerar esses elementos, pois mais abaixo vai sobrescrever seus valores.

Contudo, se você quiser zerar todos os elementos, desde o momento da alocação dinâmica, pode usar calloc() em lugar de malloc().



fclose(arq);
FILE *arq1 = fopen(arqnome, "r");


for (int j = 0; j < linhas; j++)
{
fscanf(arq1, "%s", nomeproduto[j]);
fscanf(arq1, "%d", &quantida[j]);
fscanf(arq1, "%d", &preco[j]);

}

int total = 0;
for (int k = 0; k < linhas; k++) {
total = total + (preco[k] * quantida[k]);


A maneira mais usual de expressar isso em C seria “total += preco[k]*quantida[k];”. E você não precisaria de ter esperado até aqui para calcular isso: como o preço e a quantidade de cada produto dependem só de si mesmos, e não de outros produtos, você já poderia ter acumulado esse total no mesmo laço de repetição em que faz a leitura, após ler todos os campos de cada registro.

	}

printf("\nA soma dos preocos dos produtos eh %d", total);
printf("\n");
fclose(arq1);
setbuf(stdin, NULL);


Esse uso de setbuf() é errado, violando um restrição expressa da função setbuf(), de acordo com o padrão do C (§7.21.5.6, parágrafo 2, do padrão do C de 2018), que diz que setvbuf() (que é a função chamada internamente por setbuf(), de acordo com a §7.21.5.5 do mesmo padrão) só pode ser invocada sobre um stream que tenha acabado se ser aberto e que ainda não tenha sofrido nenhuma operação de entrada ou de saída. Não é o caso de stdin no seu programa.

Se sua preocupação e intenção é retirar do buffer de entrada caracteres que não lhe interessam, a maneira correta de fazer é ler tais caracteres, certificar-se de que realmente não lhe interessam, e então descartá-los.

	printf("\nprecione qualquer tecla para encerrar o programa\n");
int verificar;
scanf("%c", verificar);
if (isdigit(verificar)!=0 || isdigit(verificar)==0)
{
exit(1);
}
}


------------
† Isso já foi discutido à exaustão aqui no fórum da comunidade. Se você fizer uma busca, logo encontrará.

‡ Entre outras possíveis fontes, a documentação de scanf() que acompanha as bibliotecas de desenvolvimento do Linux é muito boa. Se você usar Linux, pode ler sobre a função no terminal, através do comando “man scanf”. Caso não use Linux ou não possua a documentação instalada, pode consultar on-line, em https://linux.die.net/man/3/scanf. No padrão do C de 2018, a função é descrita na §7.21.5.2.

... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


A função perror não exibe nada, o programa só fecha. Você disse que não entendeu o motivo da verificação feita nas últimas linhas de código serem sempre verdadeiras verdadeiras, a intenção é essa mesmo, fiz isso apenas para que a janela do cmd não fosse imediatamente fechada após o programa ter finalizado. Você me disse que tem como fazer isso configurando o a janela do cmd, mas eu queria algo que fizesse isso sem a necessidade de configurações adicionais.

Com relação à verificação do scanf, vou olhar mais tarde




7. Re: Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/07/2019 - 14:01h

Matheus10772 escreveu:

A função perror não exibe nada, o programa só fecha. Você disse que não entendeu o motivo da verificação feita nas últimas linhas de código serem sempre verdadeiras verdadeiras, a intenção é essa mesmo, fiz isso apenas para que a janela do cmd não fosse imediatamente fechada após o programa ter finalizado. Você me disse que tem como fazer isso configurando o a janela do cmd, mas eu queria algo que fizesse isso sem a necessidade de configurações adicionais.


O programa não “fecha”. O programa simplesmente termina, porque assim ele foi construído — e faz sentido que assim ele tenha sido construído, porque não faz sentido continuar executando com tal situação de erro. Quem efetivamente “fecha”, impedindo que você observe o resultado do programa, é um entidade do ambiente de execução, normalmente chamada de “janela”, entidade essa que está fora do programa em C.

Sendo uma entidade externa ao programa, a forma mais adequada de evitar o inconveniente de não poder ver o resultado do programa é ajustar o comportamento do ambiente de execução. Comparativamente, ter de mexer no programa para contornar esse comportamento, é necessariamente intrusivo e paliativo — um contorno, não uma solução.

Alguns ambientes de desenvolvimento integrado (IDE) já vêm configurados para executar seu programa de um jeito que evita que a janela de execução se feche sem que você perceba. Qual seu IDE, e qual seu sistema operacional (SO)? Se você disser, talvez nós possamos ajudá-lo com uma configuração não-intrusiva sobre seus programas.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


8. Re: Problema com soma de valores armazenados em um arquivo [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 03/08/2019 - 02:19h

paulo1205 escreveu:

Matheus10772 escreveu:

A função perror não exibe nada, o programa só fecha. Você disse que não entendeu o motivo da verificação feita nas últimas linhas de código serem sempre verdadeiras verdadeiras, a intenção é essa mesmo, fiz isso apenas para que a janela do cmd não fosse imediatamente fechada após o programa ter finalizado. Você me disse que tem como fazer isso configurando o a janela do cmd, mas eu queria algo que fizesse isso sem a necessidade de configurações adicionais.


O programa não “fecha”. O programa simplesmente termina, porque assim ele foi construído — e faz sentido que assim ele tenha sido construído, porque não faz sentido continuar executando com tal situação de erro. Quem efetivamente “fecha”, impedindo que você observe o resultado do programa, é um entidade do ambiente de execução, normalmente chamada de “janela”, entidade essa que está fora do programa em C.

Sendo uma entidade externa ao programa, a forma mais adequada de evitar o inconveniente de não poder ver o resultado do programa é ajustar o comportamento do ambiente de execução. Comparativamente, ter de mexer no programa para contornar esse comportamento, é necessariamente intrusivo e paliativo — um contorno, não uma solução.

Alguns ambientes de desenvolvimento integrado (IDE) já vêm configurados para executar seu programa de um jeito que evita que a janela de execução se feche sem que você perceba. Qual seu IDE, e qual seu sistema operacional (SO)? Se você disser, talvez nós possamos ajudá-lo com uma configuração não-intrusiva sobre seus programas.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


Uso windows, e para fazer esse programa não usei IDE, apesar de as vezes usar o visual studio. Como você disse, algumas ides ja vem configuradas para não fechar a janela do cmd imediatamente após a execução, e é o caso do visual studio, mas como e já havia dito, queria algo que eu pudesse adicionar no código para que NÃO SEJA PRECISO CONFIGURAR O AMBIENTE DE EXECUÇÃO, pois e por exemplo, eu quiser levar o programa para outro computador, eu simplesmente possa executar o programa, sem precisar configurar mais nada.








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts