30/09/2018, 23:21

Fgets thêm ký tự ' ' vào cuối string nhập vào

Chào các bạn!
Mình đang học lập trình C, trong 1 bài tập mình làm theo Head first C nhưng không ra kết quả như hướng dẫn. Code bài tập như sau:

    #include <stdio.h>
    #include <string.h>

    char tracks[][80] =
    {
        "I left my heart in Havard Med school",
        "Newark, Newark - a wonderful town",
        "Dancing with a Dork",
        "From here to maternity",
        "The girl from Iwo Jima"
    };

    void find_track( char search_for[])
    {
        int i;

        for( i = 0; i < 5; i++)
        {

            if (strstr(tracks[i], search_for))
                printf("Track %i: %s
", i, tracks[i]);
        }
    }

    int main()
    {

        char search[20];

        printf("Search for: ");
        //scanf("%s", search); // thay bằng scanf thì cho kết quả như Head_first_C
        fgets(search, sizeof(search), stdin); // fgets() như trong bài hướng dẫn ko cho kết quả như Head_first_C
        printf("You are finding for '%s'.
", search);
        find_track(search);
        while(1);

        return 0;
    }

Mình kiểm tra thì nhận thấy là fgets() đưa thêm ký tự ‘ ’ vào cuối string vì thế nên match được kết quả. Mình mới học nên còn hạn hẹp. Bạn nào giúp mình giải thích vụ này với!

Tao Không Ngu. viết 01:32 ngày 01/10/2018

This post was flagged by the community and is temporarily hidden.

anon45952904 viết 01:33 ngày 01/10/2018

Mình không hiểu sao khi nhập chuỗi bằng fgets() thì chuỗi lại bị thêm ‘\n’ vào cuối bạn ạ. Đấy là 1 nguyên nhân mình tìm ra tại sao khi dùng fgets() thì hàm find_tracks() ko đưa ra kết quả. Ko bít còn nguyên nhân nào nữa không?

HelloWorld viết 01:32 ngày 01/10/2018

Khi bạn nhập fgets thì hàm sẽ kết thúc khi bạn nhấn phím enter tức là ký tự ‘\n’ sẽ được lưu vào mảng. Có cách để bạn xóa ký tự ‘\n’ đó đi.

char * remove_n;
(remove_n = strchr(search,’\n’)) != NULL ? *remove_n = ‘\0’:

Khoa NTA viết 01:31 ngày 01/10/2018

Hàm char *fgets(char *s, int size, FILE *stream); sẽ đọc với số ký tự nhỏ hơn size từ stream và lưu vào trong vùng đệm (buffer) trỏ bởi s. Việc đọc ký tự sẽ kết thúc khi gặp EOF (ký tự end-of-file - cuối tiệp) hoặc hết dòng ('\n'). Nếu có ký tự '\n' được đọc, nó sẽ được lưu vào trong vùng đệm (tức là đọc luôn ký tự '\n'). Kết thúc là sẽ đặt vào terminating-null-byte '\0' được thêm vào sau ký tự cuối được đọc.
(dịch từ documentation về fgets - man fgets)

Mà bạn muốn kết thúc 1 chuỗi thì search[strlen(search) - 1] = '\0'. Bạn có thể phát triển thành macro:

#include <string.h>
#define strcut_newline(str) ((str)[strlen(str) - 1] == '\n')? (str)[strlen(str) - 1] = '\0':0;
anon45952904 viết 01:23 ngày 01/10/2018

Mình vốn không phải là dân được đào tạo IT, mình đang cố tự học. Các bạn đừng quẳng gạch nếu mình hỏi ngu mà vẫn tự tin nhé
Nếu bằng cách nào mình để sót lại 1 vài em '\n' trong buffer trước đó thì fgets() sẽ ko nhận input từ keyboard đúng không bạn?

Vì dụ như ông scanf() chẳng hạn, ô ấy chẳng nhận em '\n' và để lại nó trong buffer thì em fgets() thả luôn vào sẽ lãnh hậu quả. right?

Tao Không Ngu. viết 01:21 ngày 01/10/2018

This post was flagged by the community and is temporarily hidden.

anon45952904 viết 01:27 ngày 01/10/2018

I guess so.

Khoa NTA viết 01:28 ngày 01/10/2018

Mình cũng đâu phải dân IT đâu Cũng tự học mà ra cả.
Như bạn @Phong_Ky_Vo nói thì đúng rồi đấy. Nhớ cẩn thận.

Bài liên quan
0