我正在尝试使用struct创建一个几乎像“bank”的程序,但是当程序应该读取字符串(变量“nome”,这是葡萄牙语中的名称)它完全忽略了“fgets”我用过。这是我谈论的部分:
printf("\nNome: \n");
fgets(vet[cont+1].nome, sizeof(vet[cont+1].nome), stdin);
我很确定可能问题在于我的对象数组的动态分配。请帮我解决这个问题,谢谢!
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;
}
答案 0 :(得分:1)
我看到的问题:
您在行中分配了错误的内存量:
vet = (CLIENTES*)malloc(num*sizeof(int));
应该是:
vet = malloc(num*sizeof(*vet));
见Do I cast the result of malloc?。答案解释了为什么不应该转换malloc
的返回值。
您在fgets
之后使用scanf
。 scanf
在流上留下换行符和其他空格字符。在此之后立即调用fgets
时,fgets
只读取空格和换行符。在调用scanf
之后和调用fgets
之前,您需要添加代码以忽略其余部分。
// Skip everything up to and including the newline.
int c;
while ( (c = getc(stdin)) != EOF && c != '\n');
之后,
fgets(vet[cont+1].nome, sizeof(vet[cont+1].nome), stdin);
应该正确读取数据。
您在行中使用了错误的值:
scanf("%d", &vet[cont+1].cpf);
cpf
是int
上的数组。如果您只想阅读一个int
,可以使用:
scanf("%d", &vet[cont+1].cpf[0]);
您在行中使用了错误的格式说明符:
scanf("%d", &vet[cont+1].renda_m);
应该是:
scanf("%f", &vet[cont+1].renda_m);
// ^^ %f not %d
您使用了错误的索引来访问数组vet
。您使用vet[cont+1]
的任何地方都应该是vet[cont]
。通过使用vet[cont+1]
,您不会使用数组的第一个元素vet[0]
,并且访问内存超出了您通过访问vet[num]
时所分配的内容。
如果您解决了上述问题,您的程序可能会有效。
答案 1 :(得分:1)
以下代码:
1)纠正我在评论中列出的所有问题。
2)删除了OP发布代码的一些功能,
适当注意使用while(getchar()...循环来清理剩余空白区域的标准输入。
如果用户试图在nome字段中输入任何空格,3)仍然会失败
4)代码总是检查错误
5)代码总是清理(退出前使用'free(vet);'
)编译时,始终启用所有警告, (对于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
答案 2 :(得分:0)
还有一个版本,带有循环和功能。
#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