Lặp vô tận khi nhập sai kiểu dữ liệu

int inpID()
{
    int studentID = -1;
    // repeat entering ID until it is valid.
    do
    {
        printf("ID [1 -> %d]: ", 100);
        scanf("%d", &studentID);
        if (studentID <= 0 || studentID > 100)
            printf("Invalid ID! Please try again...\n");
    } while (studentID <= 0 || studentID > 100);

    return studentID;
}

Mình viết code để nhập ID từ 1 đến 100. code chạy đúng khi mình nhập vào là một số integer. nhưng lúc mình nhập vào mà không phải integer (ví dụng mình nhập “a”) thì lỗi lặp vô tận. có ai biết cách khắc phục lỗi ko ạ

Bạn phải tìm đọc cái gọi là exception handler, tức là sử dụng try… catch để bắt lỗi nhập liệu nhé. Cái exception đó lúc mới lập trình người ta chưa giới thiệu vì ban đầu chủ yếu là nhập đúng để xem chương trình chạy ra làm sao đã, không phải là cho người dùng nào đó nhập liệu.

4 Likes

Ý tưởng lên tí nào, trước khi cho dữ liệu vào xét điều kiện thì bạn phải kiểm tra coi nó là 1 số chưa đã, đúng kiểu dữ liệu chưa rồi hẳn cho vào xét điều kiện là hết lặp vô tận thôi.

1 Like

Lỗi ở chỗ

scanf("%d", &studentID);

Hãy chuyển %d thành %c và kiểm tra ký tự được nhập là số hay là chữ. nếu là số mới kiểm tra tiếp còn là chữ thì hãy thực hiện xử lý lỗi của bạn.

1 Like

Có lẽ cậu chưa biết, nhưng hàm scanf thực ra có giá trị trả về đấy :smiley:

From manual:

int
scanf(const char *restrict format, ...);

và đây là ý nghĩa của giá trị trả về, cũng trong manual:

RETURN VALUES
These functions return the number of input items assigned. This can be fewer than provided for, or even zero, in the event of a matching failure. Zero indicates that, although there was input available, no conversions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d’ conversion. The value EOF is returned if an input failure occurs before any conversion such as an end-of-file occurs. If an error or end-of-file occurs after conversion has begun, the number of conversions which were successfully completed is returned.

Cậu có thể tham khảo implement dưới đây của tớ về cách dùng giá trị trả về của scanf để xác định đầu vào có là số nguyên không. Vì format của tớ là “%d”, vậy nên:

  • Nếu scanf trả về 1, tức là gán thành công 1 biến int
  • Nếu scanf trả về 0, tức là không gán thành công biến int nào => người dùng đã nhập sai kiểu.

Nhớ là nếu dùng scanf, cậu luôn phải cân nhắc clear buffer.

int getIntBetween(int lower, int upper) {
  int res;

  do {
    res = getInt();
    if(res < lower || res > upper) {
      printf("Invalid integer. Please enter another integer in range [%d, %d] again!\n", lower, upper);
    }
  } while(res < lower || res > upper);

  return res;
}

int getInt() {
  int result;

  while(scanf("%d",&result) != 1) {
    printf("This is not an integer number. Please retype the input: ");
    while(getchar() != '\n');
  }
  while(getchar() != '\n');

  return result;
}
4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?