Từ 1 tới 8 trên tổng số 8 kết quả

Đề tài: Lỗi Struct ?

  1. #1
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Mặc định Lỗi Struct ?

    Em có một bài tập demo về cấu trúc. Tạo một cấu trúc về hồ sơ nhân viên, nhập và xuất ra màn hình các thông tin đó.
    Đây là bài làm của em:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct HoSo
    {
           char *hoten;
           int tuoi;
           char *chucvu;
    };
    
    int main()
    {
        struct HoSo nv;
        nv.hoten = (char*)malloc(sizeof(char*));
        nv.chucvu = (char*)malloc(sizeof(char*));
        printf("Ho ten:");
        gets(nv.hoten);
        printf("Tuoi:");
        scanf("%d",&nv.tuoi);
        printf("Chuc vu:");
        gets(nv.chucvu);
        system("cls");
        printf("%s\n",nv.hoten);
        printf("%d\n",nv.tuoi);
        printf("%s\n",nv.chucvu);
        return 0;
    }
    Chương trình vẫn chạy được nhưng sau khi nhập tuổi của nhân viên xong thì chương trình bỏ qua luôn bước nhập chức vụ. Em không biết lỗi gì mong các anh giúp với

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Xài chung scanf với gets không bị làm sao được hả. Coi cái này :

  3. #3
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Trùi ui em mới lẹt đẹt C mà bác chơi đến C++ làm sao em hỉu :((

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    fflush(stdin); thêm cái này sau thằng gets thử xem. Ờ quên trong box C ! Sorry bạn nha T_T.

  5. #5
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Oh ! Em sửa được rồi ! Nhưng tại sao lại phải thêm fflush(stdin) như vậy nhỉ. Bác giải thích cặn kẽ được không

  6. #6
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Mặc định Lỗi Struct ?

    Oh ! Em sửa được rồi !
    hề hề, đã nhỉ . Bác huynguyen có giải thích trong cái link mình đưa đó, cái này thì C hay C++ chắc cũng giống nhau. Đang dở sách ra học C đây hic hic. Do mình cũng không rành C cho lắm. Nhưng mình nghĩ cơ bản là thế, bạn đọc lại kĩ cái link là ok !

  7. #7
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    hi hi sướng chứ sao không ! Hi hi cái thú của lập trình !

  8. #8
    Ngày gia nhập
    12 2007
    Bài viết
    224

    Câu hỏi của bạn rơi vào đúng cái điểm dở của cin.get hoặc cin.getline đó là nó lấy phím enter trong bộ đệm.
    Để tôi giải thích từng dòng lệnh nhé:
    Đặt cin.getline(title,50); là (1)
    Đặt cin>> year; là (2)
    Giả sử bạn gõ Gone wind(enter) thì sau câu lệnh (1) biến title có giá trị là Gone wind(enter). Tôi ghi chữ (enter) tức là phím enter nhé.
    Sau khi bạn gõ 1900(enter) thì sau lệnh (2) biến year có giá trị là 1900 đồng thời trong buffer hay các bạn gọi là bộ đệm sẽ còn lại phím enter.
    Sau khi chạy lại câu lệnh yêu cầu nhập title thì đến câu lệnh (1). cin.getline nó thấy trong buffer có phím enter và nó lấy ra luôn. Kết quả là gặp lỗi như bạn thấy.
    Để sửa lỗi này thì bạn chỉ cần thêm fflush(stdin); trước câu lệnh cin.getline là xong.
    Tríc bài của anh huynguyen để trả lời câu hỏi trên ( trong C++ ) . Ở đây đơn giản lắm , trong sách PVA thì nó giải thích như thế này : khi bạn nhập 1 ký tự từ bàn phím thì ký tự ấy sẽ được chuyển vào 1 trong 2 nơi : bộ đệm bàn phím hoặc tệp stdin . Làm sao biết khi ta nhập 1 ký tự bất kỳ thì nó sẽ gửi vào đâu . Câ trả lời là nếu ta nhập ký tự trong lúc máy dừng chờ trước các hàm scanf , gets , getchar thì máy sẽ gửi ký tự vào tệp stdin . Nếu ko phải 3 hàm ấy thì là vào bộ đệm bàn phím . Tệp stdin có tính chất như sau :
    _Nếu trên stdin có dư dữ liệu ( tức là bạn bấm nhiều phím bất kỳ ) thì các hàm trên sẽ nhận được 1 phần dữ liệu mà chúng yêu cầu . Các ký tự còn lại vẫn nằm trên stdin .
    _khi stdin chưa đủ dữ liệu thì máy sẽ chờ cho đến khi người dùng nhập đủ dữ liệu vào .

    Ở đây cái sai mà bạn gặp phải là do tính chất 1 gây ra . Có thể ví dụ đơn giản như sau :
    Code:
    scanf("%d",&n);
    gets(s);
    khi bạn nhập như sau : 55 và bấm ENTER cho hàm scanf thì ký tự 55 sẽ được gán cho biến n . Nhưng ký tự ENTER vẫn còn lưu lại trên stdin và hàm gets sẽ nhận nó vì thế sẽ làm trôi hàm gets đi . Dù bạn rất muốn nhập cái gì đó cho chuỗi s nhưng cũng bó tay .
    Thế thì cách giải quyết chính là làm sạch tệp stdin . Và người ta dùng hàm fflush(FILE *filepoint) để làm sạch nó với tham số là tên con trỏ tệp stdin : fflush(stdin);

    Ở đây có 1 vấn đề khá hay : nếu bạn đảo lại thứ tự trong code trên thì sẽ ko gặp phải vấn đề trên . Tức là bạn sẽ nhập đủ cho cả 2 hàm . Vì sao vậy ? Đó là do tính chất của hàm gets . Đúng là hàm gets nhận ký tự từ bộ đệm bàn phím và sẽ chờ người dùng nhấn phím ENTER để kết thúc việc nhập cho hàm . Như vậy thì theo đúng thì ký tự ENTER sẽ còn lại trên stdin và hàm scanf ngay phía dưới sẽ bị trôi đi . Nhưng ko , hàm gets sẽ xoá nó đi khỏi stdin đấy . Vì thế hàm scanf sẽ ko bị trôi đi đâu .

Các đề tài tương tự

  1. Gửi struct thông qua socket có khác nhau giữa gửi từng field và gửi cả struct?
    Gửi bởi bptvip_pro trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 7
    Bài viết cuối: 12-05-2013, 02:35 AM
  2. Bài tập C++ làm sao truy xuất biến của struct lồng trong struct
    Gửi bởi quangnam.tamky trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 10-04-2013, 05:22 PM
  3. Lập trình C++ Giúp đỡ về điểm khác nhau giữa struct và typedef struct
    Gửi bởi huydang2410 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 27-02-2013, 10:30 AM
  4. Khác nhau giữa struct trong c và struct trong c++
    Gửi bởi nhutlv01 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 17-02-2012, 09:12 AM
  5. kiểu struct trên C++. CHo em hỏi rõ về kiểu struct???
    Gửi bởi nhonx trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 13-01-2010, 08:39 AM

Quyền hạn của bạn

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