Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 6 của 6
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Lỗi bỏ qua đối tượng khi input (với fflush stdin)

    Chẳng là em đang học OOP, em định làm mẫu một bài hoàn chỉnh có kế thừa mà hiện tại đang gặp lỗi cơ bản sau không biết giải quyết thế nào. Em sẽ giải thích lỗi sau dòng code:

    //Person.h
    Mã:
    #pragma once
    #include <iostream>
    
    using namespace std;
    class CPerson
    {
    protected:
    	string HT;
    	string NS;
    	string Q;
    };
    class CKySu : public CPerson
    {
    public:
    	string NH;
    	int NTN;
    	void Nhap();
    	void Xuat();
    };
    //Person.cpp
    Mã:
    #include "Person.h"
    #include <iostream>
    #include <conio.h>
    #include <stdio.h>
    #include <string>
    
    using namespace std;
    
    void CKySu::Nhap()
    {
    	cout << "Nhap Ho Ten: ";
    	fflush(stdin);
    	getline(cin, HT);
    	cout << "Nhap ngay sinh: ";
    	fflush(stdin);
    	getline(cin, NS);
    	cout << "Nhap que quan: ";
    	fflush(stdin);
    	getline(cin, Q);
    	cout << "Nhap nganh hoc: ";
    	fflush(stdin);
    	getline(cin, NH);
    	cout << "Nhap nam tot nghiep: ";
    	cin >> NTN;
    }
    void CKySu::Xuat()
    {
    	cout << "Ho ten: " << HT << endl;
    	cout << "Nam sinh: " << NS << endl;
    	cout << "Que quan: " << Q << endl;
    	cout << "Nam hoc: " << NH << endl;
    	cout << "Nam tot nghiep: " << NTN << endl;
    }
    //
    Mã:
    main()
    {
    int i, n;
    			CKySu ks[100];
    			cout << "Nhap so ky su: ";
    			cin >> n;
    			for (i = 0; i < n; i++)
    			{
    				cout << "Ks thu [" << i + 1 << "]: " << endl;
    				fflush(stdin);
    				ks[i].Nhap();
    			}
    			cout << "Thong tin vua nhap: " << endl;
    			for (i = 0; i < n; i++)
    			{
    				ks[i].Xuat();
    			}
    			int kq = TimNamTNGanNhat(ks, n);
    			cout << "Ky su co nam tot nghiep gan nhat la: " << kq << endl;
    system("pause");
    }
    .
    Lỗi của em cụ thể là khi nhập n là số kỹ sư muốn nhập vào thì thay vì kế đến ta nhập họ tên thì trình biên dịch chạy bỏ qua dòng lệnh đó mà chạy nhập luôn Ngày sinh. À còn một vấn đề nữa là khi em cố tình tạo 2 file Person.h và Kysu.h (cùng với file định nghĩa .cpp kèm theo), em có dùng từ khoá public để kế thừa (có khai báo include đầy đủ) theo đúng lý thuyết đã học nhưng khi cần dùng đối tượng ở lớp cơ sở (protected) thì nó lại không thấy. Tại sao lại như vậy ạ, anh nào rành giúp em với.

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Không nên sử dụng fflush(stdin). Chuẩn C/C++ quy định fflush chỉ dùng với dòng xuất (output stream, ví dụ như stdout), còn với dòng nhập (input stream, ví dụ như stdin), chương trình sẽ rơi vào trạng thái bất định (undefined behavior): điều gì cũng có thể xảy ra, có thể nó làm theo ý bạn, có thể không.

    Xem thêm: http://en.cppreference.com/w/cpp/io/c/fflush
    For input streams (and for update streams on which the last operation was input), the behavior is undefined.

    Đối với thư viện C++ trong các bản VS trước 2015, fflush có thể dùng xóa bộ đệm của dòng nhập. Tuy nhiên vì tác dụng này không theo chuẩn, không ai có thể đảm bảo rằng nó sẽ hoạt động ở các phiên bản tiếp theo của VS hay ở các trình dịch khác. Bằng chứng là đến VS 2015, đột nhiên không được nữa. Bạn không phải là người đầu tiên rơi vào trường hợp này.

    Vậy dùng gì để thay thế? Đồi với C++, dùng ignore(); với C, dùng getchar().


    Mã:
    #include <limits>#include <iostream> std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '
    ');
    Mã:
    int c;while ((c = getchar()) != '
    ' && c != EOF);

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Undefined behavior rất nguy hiểm ở chỗ là 1 số compiler sẽ giả sử rằng undefined behavior không có và sẽ cắt bớt code dựa trên undefined behavior.


    Mã:
    volatile long s=33;unsigned long x = 1UL << s;if(s>sizeof(unsigned long * BIT_CHAR)) printf("Overflowed");

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    1
    Vậy bây giờ em phải làm sao để khi nhập liệu một chuỗi vào thì trình biên dịch sẽ nhận hết giá trị của chuỗi đó (cho đến khi nhập enter). Em đang dùng Visual Studio 2015 Communicate

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Em đã hỏi thầy, và được biết là Vs-2015 với Vs-2010 bị lỗi biên dịch này, chạy trên Vs-2012 bình thường. cách khắc phục tạm lỗi này là chèn 1 dòng code y chang dòng đó :v

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi jungsunghyo
    Em đã hỏi thầy, và được biết là Vs-2015 với Vs-2010 bị lỗi biên dịch này, chạy trên Vs-2012 bình thường. cách khắc phục tạm lỗi này là chèn 1 dòng code y chang dòng đó :v
    Thầy bạn vẫn cố đấm ăn xôi dùng fflush(stdin)?
    Có lẽ thầy bạn không biết thế nào là "lập trình theo chuẩn", nó chạy là được, không cần quan tâm đến các thứ khác.
    Mình xin nhắc lại: Đây KHÔNG phải là lỗi.
    Các cách chuẩn khác, chạy được với mọi phiên bản, với mọi trình dịch mình đã đưa ra ở trên.

 

 

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
  •