1. Tuyển Mod quản lý diễn đàn. Các thành viên xem chi tiết tại đây

Lập trình-Sự hứng thú của ngôn ngữ-Vào đây để được vote

Chủ đề trong '1981 - Hội Gà Sài Gòn' bởi xinchen, 21/05/2004.

  1. 0 người đang xem box này (Thành viên: 0, Khách: 0)
  1. Kojiro

    Kojiro Thành viên mới

    Tham gia ngày:
    16/01/2003
    Bài viết:
    77
    Đã được thích:
    0
    Ôi giời, hình như không có gà nào thích dùng MSDN hay sao ấy, hay là lười dịch như Kojiro.
    Xem lại 1 chút thì thấy đoạn này:
    fgets is similar to the gets function; however, gets replaces the newline character with NULL. fgetws is a wide-character version of fgets
    Chắc khỏi cần dịch, để ví dụ ra:
    #include <stdio.h>
    #include <conio.h>
    void main(void)
    {
    char line[256];
    gets(line);
    printf("%s", line);
    fgets(line, 256, stdin);
    printf("%s", line);
    getch();
    }

    Chạy xong để ý thì sẽ thấy có 1 chút khác biệt. Mà nếu gà nào lười chạy thử thì cũng nói luôn:
    Nếu nhập vào Hello (Enter) thì lần đầu in ra
    Hello_ (con trỏ cuối dòng trên)
    còn lần sau in ra
    Hello
    _(con trỏ đầu dòng dưới)
    Vậy đó, tuỳ theo cách dùng mà chọn chứ đâu phải chọn cách nào tốt nhất đâu hả xinchen.
  2. Kojiro

    Kojiro Thành viên mới

    Tham gia ngày:
    16/01/2003
    Bài viết:
    77
    Đã được thích:
    0
    Ôi giời, hình như không có gà nào thích dùng MSDN hay sao ấy, hay là lười dịch như Kojiro.
    Xem lại 1 chút thì thấy đoạn này:
    fgets is similar to the gets function; however, gets replaces the newline character with NULL. fgetws is a wide-character version of fgets
    Chắc khỏi cần dịch, để ví dụ ra:
    #include <stdio.h>
    #include <conio.h>
    void main(void)
    {
    char line[256];
    gets(line);
    printf("%s", line);
    fgets(line, 256, stdin);
    printf("%s", line);
    getch();
    }

    Chạy xong để ý thì sẽ thấy có 1 chút khác biệt. Mà nếu gà nào lười chạy thử thì cũng nói luôn:
    Nếu nhập vào Hello (Enter) thì lần đầu in ra
    Hello_ (con trỏ cuối dòng trên)
    còn lần sau in ra
    Hello
    _(con trỏ đầu dòng dưới)
    Vậy đó, tuỳ theo cách dùng mà chọn chứ đâu phải chọn cách nào tốt nhất đâu hả xinchen.
  3. xinchen

    xinchen Thành viên mới

    Tham gia ngày:
    21/04/2004
    Bài viết:
    87
    Đã được thích:
    0
    Đã bảo là hai hàm này có cùng tính năng mà, chọn đại đi nhưng nhớ là phải có lí do đó. Nhưng có một lí do để chọn 1 trong 2 hàm này. Hiện nay theo xinchen biết thì chắc chắn tanit trả lời sẽ chính xác. Tất nhiên còn nhiều bạn khác nữa nhưng xinchen chưa thấy
    Thật ra để có thể lựa chọn chắc chắn giữa hai hàm này thì xinchen chỉ mới biết gần đây thôi. xinchen tin chắc rằng những điều này mình chẳng tìm thấy ở trường đâu. Thậm chí cả giảng viên cũng có khi không biết trong khi vấn đề này lại rất thực tiễn Trong tình hình nhân tài IT như lá mùa thu, thật ra là không ai trả lời, xinchen sẽ để topic này chìm luôn. Mấy hôm nay cứ phải vào rình để xem có được vote cho ai không chán lắm rồi.
    Hình như topic này lại chỉ có xinchen và Kojiro chơi thôi chán ghê.
  4. tanit

    tanit Thành viên rất tích cực

    Tham gia ngày:
    28/02/2002
    Bài viết:
    1.926
    Đã được thích:
    0
    chết tui rùi :)
    Xinchen@ nói , làm tanit@ giật bắn mình luôn.

    Thôi, tạm thời làm trái tay vậy nhé.
    Đúng như các bạn đã nói,
    hàm gets() và hàm fgets() có những chức năng như trên...
    ...

    Nhưng các bạn cần chú ý khi sử dụng 2 hàm này, vì nó có một số điểm khác.
    tanit@ xin đề cử 1 cái : Đó là BUFFER_LENGTH
    1 Ví dụ nha :
    =============
    #define BUFFER_LENGTH 30
    char line[BUFFER_LENGTH];
    char *p;
    p = gets (line);
    if (p == NULL) {
    /* Some error occurred, or we reached end-of-file. No input was read. */
    }
    else {
    /* Parse the line. */
    }
    ===================
    okie, chắc mọi người cũng hiểu code rồi đúng ko?

    Nhưng chuyện gì sẽ xảy ra, khi ta nhập ký tự nhiều hơn BUFFER_LENGTH ???
    Với hàm Gets(), nó sẽ ghi ngoài khả năng cho phép, và treo, hay hư bộ nhớ.

    Với Hàm fgets() , vấn đề được giải quyết.
    chỉ cần thay thế hàm gets() ở trên bằng
    p = fgets (line, BUFFER_LENGTH, stdin);
    Hàm fgets() sẽ chỉ đọc tối đa cho tới Ký tự : BUFFER_LENGTH -1, và nó sẽ thêm Ký tự NULL vào , làm chuổi kết thúc.
    Tuy nhiên , lúc này hàm fgets() cũng có 1 hạn chế nho nhỏ, hơi to to , là nó đọc luôn <return>, hay như xinchen@ nói về "
    " đó.

    góp 1 tí ý kiến vào nha.
    Có ai có ý kiến khác ko?
    to xinchen@, ko cần vote đâu (nếu đáp đúng ý xinchen@), chỉ cần xinchen@ góp sức thôi.
    thanks
  5. Kojiro

    Kojiro Thành viên mới

    Tham gia ngày:
    16/01/2003
    Bài viết:
    77
    Đã được thích:
    0
    Hay thật, xài hoài mà giờ mới thấy, vì bản tính không cẩn thận, có bao giờ bắt lỗi khi nhập từ stdin đâu.
    Ơ, đâm ra lại thần tượng tanit.
  6. xinchen

    xinchen Thành viên mới

    Tham gia ngày:
    21/04/2004
    Bài viết:
    87
    Đã được thích:
    0
    Quả không ngoài dự đoán.
    xinchen chỉ nói thêm thôi, nếu dùng gets() bạn sẽ là nạn nhân của kiểu tấn công tràn bộ đệm (buffer overflow). IBM đã khuyến cáo tuyệt đối không dùng gets() vì rất dễ tấn công hàm này điều cần quan tâm là mức thiệt hại khi bị tấn công mà thôi
    Hồi xinchen học đại học mấy ông thầy đều dùng gets() từ ví dụ đến chương trình của chính họ, cái hay nữa là chẳng thấy một cuốn dạy C nào nói về dzụ này.
    Bây giờ viết code không chỉ làm sao cho thỏa mãn nhu cầu tính năng, làm sao cho chuẩn ( dễ thay đổi, dễ hiểu, dễ port...) mà còn phải làm sao để không bị hack. Đời (programmer) là bể khổ!!!
    Vẫn vote 5 sao cho tanit và vẫn nghiên cứu để tìm cái gì đó hay hay hỏi các bạn tiếp.
  7. xinchen

    xinchen Thành viên mới

    Tham gia ngày:
    21/04/2004
    Bài viết:
    87
    Đã được thích:
    0

    Định nghĩa 1 struct có 2 thành viên:
    - a1 có độ lớn là 1 bit
    - a2 có độ lớn là 31 bit


    typedef struct a
    {
    int a1:1;
    int a2:31;
    }StructA;
    void main()
    {
    StructA a;
    a.a1 = 1;
    a.a2 = 1;
    if (a.a1==1) printf("a1 đúng là bằng 1
    ");
    else printf("a1 thật ra hổng bằng 1
    ");
    if (a.a2==1) printf("a2 đúng là bằng 1
    ");
    else printf("a2 thật ra hổng bằng 1
    ");
    }
    Kết quả xuất ra màn hình là:
    a1 thật ra hổng bằng 1
    a2 đúng là bằng 1
    Trong khi mong đợi là
    a1 đúng là bằng 1
    a2 đúng là bằng 1
    Sao kì zdậy?

  8. fukutomi

    fukutomi Thành viên mới

    Tham gia ngày:
    17/02/2003
    Bài viết:
    511
    Đã được thích:
    0
    Chạy thử thì thấy warning: comparison is always 0 due to width of bitfield.
    Có phải là vì bác set cho a1 là 1 bit nên nó mới warning là không đủ chổ để chứa int a1 = 1 phải không. Vì thế nên nó mới execute cái else. Còn cái a2 vì có bitwidth là 31 nên có thể chứa a2=1 nên nó execute cái if
    Chẹp, mới ôn lại C nên quên ráo trọi, mong bác chỉ giáo nếu em sai
  9. xinchen

    xinchen Thành viên mới

    Tham gia ngày:
    21/04/2004
    Bài viết:
    87
    Đã được thích:
    0
    1 bit thì lưu được 2 giá trị
    2 bit thì lưu được 4 giá trị ...
    Mặc dù xinchen không giao trước là không chạy thử đoạn code nhưng nếu được thì bạn dùng cách này thì mất đi 3/4 sự thú vị rồi.
    Thêm một điều nữa là bạn đã biên dịch thử rồi mà vẫn chưa trả lời được thuyết phục thì uổng quá. Có ai tiếp tục không?
    xinchen dùng C/C++ hoài mà còn không biết nhiều vần đề nữa là... xinchen đang vẫn phải tiếp tục luyện nè.
  10. xinchen

    xinchen Thành viên mới

    Tham gia ngày:
    21/04/2004
    Bài viết:
    87
    Đã được thích:
    0
    xinchen phải trả lời thôi. Tiếc cho bạn gì đó ở Japan bạn đã nhìn thấy giá trị khác nhưng lại không thấy nó là -1 và không đi tiếp nữa.
    Đây là một vấn đề của LVT. Đôi khi chúng tôi viết xong một đoạn code, trình biên dịch không phàn nàn gì cả, biên dịch ầm ầm nhưng cuối cùng chạy ra kết quả sai. Nếu mà xui đạn không tìm được chổ sai có khi phải viết lại toàn bộ theo hướng khác.
    Ở đâu do khi dùng một ô nhớ có độ dài 1 bit tôi đã khai báo theo kiểu có dấu, vì vậy nó sẽ chứa được 2 số đó là 0 và -1 chứ không phải như là số 0 và 1 như mong đợi.
    Sửa lại bằng cách khai báo
    unsigned int abit:1;
    Tới đây xinchen xin kết thúc màn trình diễn, khi nào thấy có nhu cầu thì xinchen sẽ trở lại. Không ngờ dân IT của hội gà giỏi quá mấy câu đố như thế này không làm họ quan tâm.
    Nếu có ai muốn tìm thách thức thì qua bên Java, C++ kiếm xinchen nha. Thật ra xinchen đang nghiên cứu thói quen lập trình nên rất cần ý kiến của các bạn.
    RẤT MONG NHẬN ĐƯỢC SỰ GIÚP ĐỠ

Chia sẻ trang này