[英]Why I cannot use "fgets" to read a string to an element of my Struct?
I'm trying to create a program almost like "bank" using struct, but when the program should have read the string (variable "nome" that is name in portuguese) it totally ignore the "fgets" that I used .我正在尝试使用结构创建一个几乎类似于“bank”的程序,但是当程序应该读取字符串(葡萄牙语中的名称变量“nome”)时,它完全忽略了我使用的“fgets” 。 This is the part that I was talking about :这是我正在谈论的部分:
printf("\nNome: \n");
fgets(vet[cont+1].nome, sizeof(vet[cont+1].nome), stdin);
And I'm pretty sure that maybe the problem is with the dynamically allocation of my object array.而且我很确定问题可能出在我的对象数组的动态分配上。 Please, give me a help with this problem, thank you!请帮我解决这个问题,谢谢!
PS: I'm sorry but the code is in portuguese (my native language). PS:对不起,代码是葡萄牙语(我的母语)。
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
/*
Programa realiza uma alocacao dinamica por meio
de uma funcao que recebe a dimensao e retorna o vetor(ponteiro)
*/
struct CLIENTES
{
int ano_nasc, cpf[11];
float renda_m;
char nome[50];
}; //Lista de Objetos
int main(void)
{
//Declaracao de Variaveis
int cont=0, num, num_2, client, i, j;
CLIENTES *vet;
//Leitura de Dados
printf("Digite o numero de Clientes: ");
scanf("%d", &num);
vet = (CLIENTES*)malloc(num*sizeof(int));
printf("Digite os Dados do Cliente.");
while (cont != num)
{
printf("\nNome: \n");
fgets(vet[cont+1].nome, sizeof(vet[cont+1].nome), stdin);
printf("\nAno de Nascimento: ");
scanf("%d", &vet[cont+1].ano_nasc);
printf("\nCPF: ");
scanf("%d", &vet[cont+1].cpf);
printf("\nRenda Mensal: ");
scanf("%d", &vet[cont+1].renda_m);
cont++;
}
printf("\nDigite o numero do cliente que voce deseja conferir: ");
scanf("%d", &num_2);
for (i=0;i<num;i++)
{
if(num_2 == num)
{
printf("\nO que deseja saber sobre ele?\n");
printf("1-Nome\n2-Ano de Nascimento\n3-CPF\n4-Renda Mensal\n\n\n");
scanf("%d", &client);
if (client == 1)
{
printf("Nome: %c", vet[num_2].nome );
}
else if(client == 2)
{
printf("Ano de Nascimento: %d", vet[num_2].ano_nasc );
}
else if(client == 3)
{
for(j=0;j<11;j++)
{
printf("CPF: %d", vet[num_2].cpf[j]);
}
}
else if(client == 4)
{
printf("Renda Mensal: %f", vet[num_2].renda_m );
}
}
}
//Finalizando o Programa
printf("\n\nFim do Programa!");
getch();
return 0;
}
Problems that I see: 我看到的问题:
You are allocating the wrong amount of memory in the line: 您在该行中分配了错误的内存量:
vet = (CLIENTES*)malloc(num*sizeof(int));
That should be: 应该是:
vet = malloc(num*sizeof(*vet));
See Do I cast the result of malloc? 请参见是否强制转换malloc的结果? . 。 The answers explain why you should not cast the return value of malloc
. 答案解释了为什么不应该malloc
的返回值。
You are using fgets
after a scanf
. 您在scanf
之后使用fgets
。 scanf
leaves the newline and other whitespace characters on the stream. scanf
将换行符和其他空白字符留在流中。 When fgets
is called right after that, fgets
reads just the whitespace and the newline. 此后立即调用fgets
, fgets
仅读取空白和换行符。 You need to add code to ignore the rest of the line after the call to scanf
and before the call to fgets
. 您需要添加代码,以忽略对scanf
的调用之后和对fgets
的调用之前的其余部分。
// Skip everything up to and including the newline. int c; while ( (c = getc(stdin)) != EOF && c != '\\n');
after that, 之后,
fgets(vet[cont+1].nome, sizeof(vet[cont+1].nome), stdin);
should read the data correctly. 应该正确读取数据。
You are using the wrong value in the line: 您在该行中使用了错误的值:
scanf("%d", &vet[cont+1].cpf);
cpf
is an array on int
s. cpf
是int
的数组。 If you want to read just one int
, you can use: 如果您只想读取一个int
,则可以使用:
scanf("%d", &vet[cont+1].cpf[0]);
You are using the wrong format specifier in the line: 您在该行中使用了错误的格式说明符:
scanf("%d", &vet[cont+1].renda_m);
It should be: 它应该是:
scanf("%f", &vet[cont+1].renda_m); // ^^ %f not %d
You are using the wrong index to access the array vet
. 您使用了错误的索引来访问数组vet
。 Everywhere you use vet[cont+1]
, it should be vet[cont]
. 您在使用vet[cont+1]
地方都应该是vet[cont]
。 By using vet[cont+1]
, you are not using the first element of the array, vet[0]
, and accessing memory beyond what you allocated for when by accessing vet[num]
. 通过使用vet[cont+1]
,您将不使用数组的第一个元素vet[0]
,并且访问的内存超出了通过访问vet[num]
分配的内存。
If you fix the above problems, your program might work. 如果解决上述问题,则程序可能会运行。
the following code: 以下代码:
1) corrects all the problems I listed in the comments. 1)纠正我在评论中列出的所有问题。
2) drops some of the functionality of the OPs posted code, 2)删除了OP发布代码的某些功能,
Due notice the usage of a while( getchar() ... loop to clean the stdin of any remaining white space. 请注意,使用while(getchar()...循环)可清理标准输入中的所有剩余空白。
3) will still fail if the user tries to enter any white space in the nome field 3)如果用户尝试在nome字段中输入任何空格,仍然会失败
4) the code always checks for errors 4)代码总是检查错误
5) the code always cleans up (with 'free( vet );' before exiting 5)退出之前,代码始终会清理(使用“ free(vet);”
when compiling, always enable all the warnings, (for gcc, at a minimum, use '-Wall -Wextra -pedantic') 编译时,始终启用所有警告(对于gcc,至少要使用“ -Wall -Wextra -pedantic”)
#include <stdio.h>
//#include <conio.h> // not portable, do not use
#include <stdlib.h>
/*
Programa realiza uma alocacao dinamica por meio
de uma funcao que recebe a dimensao e retorna o vetor(ponteiro)
*/
#define NUM_CPF (11)
#define MAX_NOME_LEN (50)
struct CLIENTES
{
int ano_nasc;
int cpf[NUM_CPF];
float renda_m;
char nome[ MAX_NOME_LEN ];
}; //Lista de Objetos
int main(void)
{
//Declaracao de Variaveis
int cont=0;
int num;
int client;
int i;
int j;
struct CLIENTES *vet = NULL;
//Leitura de Dados
printf("Digite o numero de Clientes: ");
if( 1 != scanf("%d", &num) )
{ // scanf failed
perror( "scanf for num failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// clear stdin
while( getchar() != '\n' );
if( NULL == (vet = malloc(num*sizeof(struct CLIENTES)) ) )
{ // then malloc failed
perror( "malloc for multiple struct CLIENTES failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
while (cont != num)
{
printf("\nNome: ");
fflush(stdout);
if( NULL == fgets(vet[cont].nome, MAX_NOME_LEN, stdin) )
{ // fgets failed
perror( "fgets failed" );
free( vet );
exit( EXIT_FAILURE );
}
// implied else, fgets successful
// clear stdin
//while( getchar() != '\n' );
printf("\nAno de Nascimento: ");
if( 1 != scanf("%d", &vet[cont].ano_nasc) )
{ // scanf failed
perror( "scanf for ano_nasc failed" );
free( vet );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("\nCPF: ");
if( 1 != scanf("%d", vet[cont].cpf) )
{ // scanf failed
perror( "scanf for cpf failed" );
free( vet );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf("\nRenda Mensal: ");
if( 1 != scanf("%f", &vet[cont].renda_m) )
{ // scanf failed
perror( "scanf for renda_m failed" );
free( vet );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// clear stdin
while( getchar() != '\n' );
cont++;
} // end while
for (i=0;i<num;i++)
{
printf("\nO que deseja saber sobre ele?\n");
printf("1-Nome\n2-Ano de Nascimento\n3-CPF\n4-Renda Mensal\n\n\n");
if( 1 != scanf("%d", &client) )
{ // scanf failed
perror( "scanf for client failed" );
free( vet );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
switch( client )
{
case 1:
printf("Nome: %49s", vet[i].nome );
break;
case 2:
printf("Ano de Nascimento: %d", vet[i].ano_nasc );
break;
case 3:
for(j=0; j< NUM_CPF; j++)
{
printf("CPF[%d] = %d", j, vet[i].cpf[j]);
}
printf( "\n" );
break;
case 4:
printf("Renda Mensal: %f", vet[i].renda_m );
break;
default:
printf("ERROR: invalid client value, range 1...4\n");
break;
}; // end switch
} // end for
//Finalizando o Programa
printf("\n\nFim do Programa!");
free( vet );
system( "pause" );
return 0;
} // end function: main
One more version, with loops and functional.又一个版本,带有循环和功能。
#include <stdio.h>
//#include <conio.h> // not portable, do not use
#include <stdlib.h>
/*
Programa realiza uma alocacao dinamica por meio
de uma funcao que recebe a dimensao e retorna o vetor(ponteiro)
*/
#define NUM_CPF (11)
#define MAX_NOME_LEN (50)
struct CLIENTES
{
int ano_nasc;
int cpf[NUM_CPF];
float renda_m;
char nome[ MAX_NOME_LEN ];
}; //Lista de Objetos
void soErros(char erro[20]){
perror(erro);
exit( EXIT_FAILURE );
}
int main(void)
{
//Declaracao de Variaveis
int cont=0;
int num;
int client, saida;
int i;
int j;
int k;
struct CLIENTES *vet = NULL;
//Leitura de Dados
printf("Digite o numero de Clientes: ");
if( 1 != scanf("%d", &num) )
{ // scanf failed
soErros("scanf for num failed" );
}
// implied else, scanf successful
// clear stdin
while( getchar() != '\n' );
if( NULL == (vet = malloc(num*sizeof(struct CLIENTES)) ) )
{ // then malloc failed
soErros("malloc for multiple struct CLIENTES failed");
}
// implied else, malloc successful
while (cont != num)
{
printf("\nNome: ");
fflush(stdout);
if( NULL == fgets(vet[cont].nome, MAX_NOME_LEN, stdin) )
{ // fgets failed
soErros("fgets failed");
}
// implied else, fgets successful
// clear stdin
//while( getchar() != '\n' );
printf("\nAno de Nascimento: ");
if( 1 != scanf("%d", &vet[cont].ano_nasc) )
{ // scanf failed
soErros("scanf for ano_nasc failed");
}
// implied else, scanf successful
printf("\nCPF: ");
if( 1 != scanf("%d", vet[cont].cpf) )
{ // scanf failed
soErros("scanf for cpf failed");
}
// implied else, scanf successful
printf("\nRenda Mensal: ");
if( 1 != scanf("%f", &vet[cont].renda_m) )
{ // scanf failed
soErros("scanf for renda_m failed");
}
// implied else, scanf successful
// clear stdin
while( getchar() != '\n' );
cont++;
} // end while
int escolha = 0;
do{
int *esc = &escolha;
printf("\nDeseja saber sobre qual cliente?: ");
for (i=0;i<num;i++)
{
printf("\n%d --- %s",i , vet[i].nome);
} // end for
if( 1 != scanf("%d", &esc) )
{ // scanf failed
soErros("scanf for ano_nasc failed");
} // end if
printf("\nVocê escolheu o cliente %s", vet[escolha].nome);
for(i=0;i<num;i++)
{
if(i == escolha){
printf("\n0-Sair\n1-Nome\n2-Ano de Nascimento\n3-CPF\n4-Renda Mensal\n");
if( 1 != scanf("%d", &client) )
{ // scanf failed
soErros("scanf for client failed");
}
// implied else, scanf successful
switch( client )
{
case 0:
printf("Saindo do menu");
break;
case 1:
printf("Nome: %49s", vet[i].nome );
break;
case 2:
printf("Ano de Nascimento: %d", vet[i].ano_nasc );
break;
case 3:
printf("CPF = ");
for(j=0; j< NUM_CPF; j++)
{
printf("%d", vet[i].cpf[j]);
}
printf( "\n" );
break;
case 4:
printf("Renda Mensal: %f", vet[i].renda_m );
break;
default:
printf("ERROR: invalid client value, range 1...4\n");
system("cls || clear");
break;
}; // end switch
printf( "\n" );
} // end if
} //end for
printf("Continuar[1]\nSair[0]\n: ");
if( 1 != scanf("%d", &saida) )
{
soErros("Erro de continuidade");
} // end if
switch( saida )
{
case 0:
break;
}
} // end do
while (saida);
//Finalizando o Programa
printf("\nFim do Programa!\n");
free( vet );
system( "pause" );
return 0;
} // end function: main
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.