30/09/2018, 17:25

Hỏi về giá trị của hàm getchar() trong C

Em có đoạn code như này:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int houseNumber;
    printf("Your house's number is: ");
    scanf("%d", &houseNumber);

    char fullName[20] ;
    char c;
    int i = 0;
    printf("Your name is: ");

    do {
        c = getchar();
        fullName[i] = c;
        i++;
    } while (c != '
');

    fullName[i] = 0;
    printf("%s, Sure?", fullName);
}

Nhưng sau khi chạy thì đến đoạn scanf đầu tiên xong ấn Enter thì nó chạy xong ct luôn, e mày mò 1 lúc thì thử thêm:

c = getchar();
c = 0;

như thế này:

#include <stdio.h>
#include <stdlib.h>  
int main()
{
    int houseNumber;
    printf("Your house's number is: ");
    scanf("%d", &houseNumber);

    char fullName[20] ;
    char c;

    c = getchar();
    c = 0;

    int i = 0;
    printf("Your name is: ");

    do {
        c = getchar();
        fullName[i] = c;
        i++;
    } while (c != '
');

    fullName[i] = 0;
    printf("%s, Sure?", fullName);
}

thì nó chạy ok, vậy em suy ra là hàm getchar() nó sẽ lấy default value là ký tự gần nhất ta nhập từ bàn phím vào đúng ko ạ, em cũng search rồi nhưng đọc tiếng anh ko hiểu lắm nên hỏi lại cho chắc ăn.

Nếu đúng thì có cách nào để ko cần viết 2 dòng đó mà vẫn được ko?
Vì lặp lại 2 lần c = getchar() em thấy ngứa mắt lắm.

Minh Hoàng viết 19:26 ngày 30/09/2018

Returns the next character from the standard input (stdin).
http://www.cplusplus.com/reference/cstdio/getchar/?kw=getchar

chính xác hơn là lấy từ stdin. Bạn có thể dùng fflush(stdin); để xóa đi bộ đệm bàn phím.

Dung Nguyen viết 19:31 ngày 30/09/2018

fflush(stdin);

Thank anh! em thử ngon rồi.

viết 19:28 ngày 30/09/2018

fflush là dành cho output stream. Xài trên input stream (ở đây là stdin) có thể có kết quả ko xác định.
http://c-faq.com/stdio/stdinflush.html

while((c = getchar()) != '\n' && c != EOF);

vậy cũng 1 dòng mà bảo đảm
http://c-faq.com/stdio/stdinflush2.html

Minh Hoàng viết 19:35 ngày 30/09/2018

ok, thank bạn.

In some implementations, flushing a stream open for reading causes its input buffer to be cleared (but this is not portable expected behavior).

lý do vì sao nhỉ?

viết 19:38 ngày 30/09/2018

ta nghĩ là vì đại khái nó ko có lý lắm. Vì output ra file chậm nên thường phải chờ ghi 1 lượng lớn thì nó mới bắt đầu thực hiện, ví dụ chờ ghi đủ 4KB thì mới bắt đầu ghi vào đĩa cứng. Trong khi mấy log file thì cần xong dòng nào ghi dòng đó vào đĩa liền, chứ chờ đủ 4KB thì ví dụ mới 2KB thì cúp điện, log file mất ~20 dòng, trong khi đáng lẽ ko mất dòng nào nếu sau mỗi dòng thì flush output file 1 cái. Vậy nên fflush có nghĩa cho output stream.

còn với input stream thì chả lẽ mở file lên flush 1 cái hết nội dung file, vậy flush file làm gì, chỉ cần đóng file hay fseek tới end file là xong rồi… Nếu chỉ áp dụng “độc quyền” cho stdin, hay đúng hơn là “độc quyền” cho ignore 1 dòng của stdin thì nên viết code thực hiện đúng chức năng đó. Vd 1 người copy 2 đoạn văn bản rồi paste vào command line, như vậy ở giữa 2 đoạn văn bản có 1 dấu ‘\n’, đáng lẽ phải đọc được 2 đoạn thì nay chỉ đọc được 1 đoạn, đoạn thứ 2 bị flush bay mất thay vì chỉ cần ignore tới ‘\n’ ở giữa là được rồi.

Minh Hoàng viết 19:40 ngày 30/09/2018

vậy thì tùy yêu cầu nhập mà mình sử dụng các cách khác nhau thôi, tks

Bài liên quan
0