User Tag List

+ Trả lời chủ đề
Hiện kết quả từ 1 tới 7 của 7

Chủ đề: Gặp vấn đề khi nhập xâu

  1. #1
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Gặp vấn đề khi nhập xâu

    Mình có một chương trình C như sau:
    PHP Code:
    #include<stdio.h>
    int main()
    {
            
    char s[20];
            
    int n;
            
    printf("N = ");
            
    scanf("%d",&n);
            
    printf("Nhap xau: ");
            
    fflush(stdin); fgets(s,20,stdin);
            
    printf("%s\n",s);
            return 
    0;

    Biên dịch thì ngon lành (trên Linux) nhưng lúc chạy thì gặp vấn đề là sau khi nhập N xong thì nó không đợi mình nhập xâu mà kết thúc ngay chương trình.

    Mã:
    N = 5
    Nhap xau: 
    //đến đây chương trình đã kết thúc
    Mình nghĩ là vẫn còn ký tự xuống dòng trong bộ nhớ đệm nhưng rõ ràng mình đã xóa bộ nhớ đệm bằng hàm fflush(stdin) rồi mà
    Contact me:
    Email: sangnd [at] svBK.vn
    Personal website: My Blog | Chat với người lạ
    Facebook Page của Bách Khoa Forum: http://www.facebook.com/svbk.vn

  2. #2
    Điều hành viên Avatar của iexplore
    Tham gia ngày
    Sep 2010
    Bài gửi
    208

    Mặc định

    Trên Win 7 vẫn chạy bình thường mà, không thấy có lỗi gì cả

  3. #3
    Khánh Hòa
    Tham gia ngày
    Apr 2010
    Bài gửi
    159

    Mặc định Re: Gặp vấn đề khi nhập xâu

    Trên win7 vẩn bt, mình ko hiểu

  4. #4
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Re: Gặp vấn đề khi nhập xâu

    Chưa thử nhưng tớ cũng đoán là trên Windows thì cái này chạy bình thường, còn trên Linux thì nó như vậy và đang tìm hiểu

    À, nhân tiện khuyến cáo anh em nên sử dụng hàm fgets để nhập xâu thay cho hàm gets vì hàm gets không quản lý được số ký tự tối đa nhập vào nên có thể gây lỗi buffer overrun.

    Ví dụ ta khai báo: char s[20] mà nhập xâu bằng gets thì nếu người dùng nhập >20 ký tự sẽ gây ra lỗi.

    Cú pháp hàm fgets như hôm nọ thầy Phương dậy nhé

    char buf[80];
    gets(buf);
    fgets(buf, 80, stdin);

    Như vậy, hàm fgets đa năng hơn. Ngoài ra, có 1 chi tiết hết sức quan trọng, đó là dùng hàm fgets không sợ bị lỗi bảo mật buffer overrun. Đó chính là lý do tại sao nhiều sách khuyến cáo chúng ta không nên dùng hàm gets nữa, vì nó không được an toàn.

  5. Có 3 thành viên cảm ơn bài viết của 1973 có chất lượng:


  6. #5
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Re: Gặp vấn đề khi nhập xâu

    Mang cái này đi hỏi thì tìm được câu trả lời trong bài này rất hay: http://ubuntuforums.org/showthread.php?t=83694

    **************

    ATTN: This is for newbies to programming. I guess the pros must have known this all along.

    I'm taking a subject called Programming Principles and Techniques. Basically it's an intro to programing class using C languange. The IDE installed at the computer lab and classroom is MS Visual C++. And after each lecture, I went back home at tried the lesson on Ubuntu using Anjuta. All went fine, until the lecturer teaches about fflush (stdin). Here's what I found out.

    This is the problem that my lecturer ask us to solve:

    PHP Code:
    #include <stdio.h>

    int main()
    {
        
    int n;
        
    char string[80];
        for (
    n=0n<5n++)
            {
                
    printf ("Enter some words: ");
                
    scanf ("%s"string);
                
    printf ("The first word you entered is : %s\n"string);
            }
        return 
    0;

    This is the suggested solution:

    PHP Code:
    #include <stdio.h>

    int main()
    {
        
    int n;
        
    char string[80];
        for (
    n=0n<5n++)
            {
                
    printf ("Enter some words: ");
                
    scanf ("%s"string);
                
    printf ("The first word you entered is : %s\n"string);
                
    fflush (stdin);
            }
        return 
    0;

    To my surprise, it only works in Windows. In Linux, it ran the same with and without fflush (stdin). After searching the net, I have found that:
    According to Things to Avoid in C/C++ -- fflush(stdin), it is best to avoid using scanf. But that's the only input method my lecturer has taught so far, and I wish not to confuse myself (and my classmates that I'm gonna have to share this with later) with other input methods.

    Further search on the net lead me to these solution that works both in GNU/Linux and Windows:

    PHP Code:
    #include <stdio.h>

    int main()
    {
        
    int n;
        
    char string[80];
        for (
    n=0n<5n++)
            {
                
    printf ("Enter some words: ");
                
    scanf ("%s"string);
                
    printf ("The first word you entered is : %s\n"string);
                while (
    getchar() != '\n') continue;
            }
        return 
    0;

    PHP Code:
    #include <stdio.h>

    void clear_kb(void);

    int main()
    {
        
    int n;
        
    char string[80];
        for (
    n=0n<5n++)
            {
                
    printf ("Enter some words: ");
                
    scanf ("%s"string);
                
    printf ("The first word you entered is : %s\n"string);
                
    clear_kb();
            }
        return 
    0;
    }

    void clear_kb(void)
    {
        
    char junk[255];
        
    fgets (junk,255,stdin);

    Why can't MS just use the standard (ANSI) C???

    **********************

  7. #6
    Điều hành viên Avatar của iexplore
    Tham gia ngày
    Sep 2010
    Bài gửi
    208

    Mặc định Re: Gặp vấn đề khi nhập xâu

    PHP Code:
    while (getchar() != '\n') continue; 
    PHP Code:
    void clear_kb(void

        
    char junk[255]; 
        
    fgets (junk,255,stdin); 

    đoạn này để làm gì nhỉ? 1973 giải thích cho tớ với

  8. #7
    .:: Grumpy svBKer ::. Avatar của 1973
    Tham gia ngày
    Mar 2010
    Bài gửi
    3.793

    Mặc định Re: Gặp vấn đề khi nhập xâu

    Quote Nguyên văn bởi iexplore Xem bài viết
    PHP Code:
    while (getchar() != '\n') continue; 
    PHP Code:
    void clear_kb(void

        
    char junk[255]; 
        
    fgets (junk,255,stdin); 

    đoạn này để làm gì nhỉ? 1973 giải thích cho tớ với
    Mục đích của 2 đoạn này là để xóa ký tự xuống dòng còn tồn tại trong bộ nhớ đệm sau khi thực hiện hàm scanf.

    Về hiện tượng xảy ra đối với chương trình của tớ (trên linux) được giải thích như sau:

    - khi gặp hàm scanf, người dùng nhập số liệu và nhấn Enter, dấu xuống dòng do đó vẫn tồn tại trong bộ nhớ đệm và khiến hàm fgets sau đó bị trôi lệnh (tức là chưa kịp nhập gì nó đã kết thúc hàm).

    - để khắc phục hiện tượng này, tớ đã cố gắng xóa bộ nhớ đệm bằng hàm fflush(stdin) nhưng nó chỉ có tác dụng trên Windows còn trên Linux thì ko có tác dụng. Không phải Linux không hỗ trợ fflush(stdin) mà là fflush(stdin) không phải là chuẩn của C, trên Windows chạy được là do M$ đã phớt lờ đi điều này. Để rõ hơn về cái này mọi người đọc post #5 ở trên nhé .

    Sau một thời gian lập trình trên Linux tớ thấy rằng M$ đã xào nấu rất nhiều thứ đối với C, chỉ khi sang Linux thì mới thấy được thế nào là C chuẩn

  9. Tớ cảm ơn 1973 đã chia sẻ.


+ Trả lời chủ đề

Thông tin chủ đề

Users Browsing this Thread

Hiện có 1 người đọc bài này. (0 thành viên và 1 khách)

Từ khóa (Tag) của chủ đề này

Quyền viết bài

  • Bạn không thể gửi chủ đề mới
  • Bạn không thể gửi trả lời
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình


About svBK.VN

    Bách Khoa Forum - Diễn đàn thảo luận chung của sinh viên ĐH Bách Khoa Hà Nội. Nơi giao lưu giữa sinh viên - cựu sinh viên - giảng viên của trường.

Follow us on

Twitter Facebook youtube