2015-06-18 1 views
1

Я пытаюсь создать программу почти как «банк» с использованием структуры, но когда программа должна прочитать строку (переменная «nome», которая является именем на португальском языке) полностью игнорирует «fgets», который я использовал , Это та часть, что я говорил о:Почему я не могу использовать «fgets» для чтения строки для элемента моего Struct?

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; 
} 
+3

Почему вы таНос (Num * SizeOf (INT))? Каждый элемент - sizeof (struct CLIENTES), а не sizeof (int). – jarmod

+1

'vet = (CLIENTES *) malloc (num * sizeof (int));' должен быть таким, как 'vet = (CLIENTES *) malloc (num * sizeof (* vet));' и 'fgets (vet [cont + 1] .nome, sizeof (vet [cont + 1] .nome), stdin); 'remove' + 1'. – BLUEPIXY

+0

Спасибо, ребята, за помощь, но я сделал все изменения, и программа все еще не может читать мои фэки. –

ответ

1

Проблемы, которые я вижу:

  1. Вы выделяют неправильный объем памяти в линейке:

    vet = (CLIENTES*)malloc(num*sizeof(int)); 
    

    Это должно быть:

    vet = malloc(num*sizeof(*vet)); 
    

    См Do I cast the result of malloc?. Ответы объясняют, почему вы не должны указывать возвращаемое значение malloc.

  2. Вы используете 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); 
    

    должны правильно считывать данные.

  3. Вы используете неправильное значение в строке:

    scanf("%d", &vet[cont+1].cpf); 
    

    cpf массив на int с. Если вы хотите прочитать только один int, вы можете использовать:

    scanf("%d", &vet[cont+1].cpf[0]); 
    
  4. Вы используете неправильный спецификатор формата в строке:

    scanf("%d", &vet[cont+1].renda_m); 
    

    Оно должно быть:

    scanf("%f", &vet[cont+1].renda_m); 
        // ^^ %f not %d 
    
  5. Вы используете неправильный указатель для доступа к массиву vet. Всюду вы используете vet[cont+1], это должно быть vet[cont]. Используя vet[cont+1], вы не используете первый элемент массива, vet[0] и получаете доступ к памяти за пределами того, что вы выделили, когда обратились к vet[num].

Если вы исправите вышеуказанные проблемы, ваша программа может работать.

+0

Спасибо за помощь, я исправил некоторые моменты, которые вы только что сказали, но прямо сейчас я не могу напечатать строку, которую я только что написал, и я не знаю, почему, любая идея? –

+1

@GabrielMello, возможно, было бы лучше начать новый вопрос после включения моих исправлений в ваш код. –

+0

Хорошо, спасибо за предложение! –

1

следующий код:

1) исправляет все проблемы, я перечислил в комментариях.

2) падает некоторые из функциональных вуп вывешенных кода,

Из-уведомления использования некоторого времени (GetChar() ... петля для очистки стандартного ввода любого оставшегося белого пространства.

3) все равно будет ошибка, если пользователь пытается войти в любом пустом пространство в номе поля

4) код всегда проверяет наличие ошибок

5) код всегда убирает (с «бесплатно (ветами);» до выхода

при компиляции, всегда включайте все предупреждения, (для НКУ, как минимум, использовать '-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 
+0

Спасибо Я использовал «fflush (stdin)» в начале цикла, и теперь код работает отлично! –

Смежные вопросы