01/10/2018, 08:36

Vấn đề đọc file txt trong C /C++

Chào mọi người, mọi người giải đáp cho em khúc mắt chổ này. Giả sử em có file input.txt với nội dung là dãy các số thực: 1.2 1.3 1.4 1.5 1.6___ ( phía cuối có các khoảng trắng)
khi em đọc file bằng thư viện stdio.h và thư viện ifstream lần lượt như sau:

//thư viện stdio.h
void readFile(char* fileName){
 FILE* fp = fopen(fileName,"rt");
 if ( !fp ) {
    cerr<<"error!!"; return;
}
float temp = 0;
while( !feof(fp)) {
   fscanf(fp, "%f", &temp);
   cout << temp << "  ";
 }
  cout << endl;
  fclose(fp);
}

khi đó chương trình sẽ xuất ra dãy số như trên nhưng số 1.6 được lặp lại 2 lần: 1.2 1.3 1.4 1.5 1.6 1.6
khi thêm vào đoạn code sau:

        if (fscanf(fp, "%f", &temp) > 0)
			cout << temp << "  ";
		else
			break;

tức là chương trình trở thành:

void readFile2(char* fileName) {
	FILE* fp = fopen(fileName, "rt");
	if (!fp)
		cerr << "khong the mo file!!" << endl;
	float temp = 0;
	while (!feof(fp)) {
		
		if (fscanf(fp, "%f", &temp) > 0)
			cout << temp << "  ";
		else
			break;
	}
	cout << endl;
	fclose(fp);

}

thì chương trình mới chạy đúng. Mình hiểu là vì cuối file có khoảng trắng nên nếu đọc bằng cách 1 thì đọc hết 1.6 rồi dòng !feof(fp) vẫn còn đúng nên vẫn tiếp tục đọc nhưng nếu vậy tại sao khi xuất ra biến temp vẫn có giá trị là 1.6 sau khi đã qua lệnh fscanf(fp, "%f", &temp);

Tương tự khi viết bằng ifstream thì 2 cách viết

while (!fp.eof()) {
  fp >> temp;
  cout<<temp<<"  ";
}

 while (!fp.eof()) {
	if ( ! (fp >> temp) )
		break;
	cout << temp<<endl;
}

cũng cho ra kq tương tự. a LTD giải thích dùm em lý do được không ạ. tại sao biến temp lại chưa giá trị 1.6 2 lần mà k bị thay đổi giá trị.


rogp10 viết 10:51 ngày 01/10/2018

Không được viết kiểu while(!eof()) chính vì lí do này
Đó là vì eof chỉ trigger sau lần đọc bị lố, kiểu như là lỗi ấy.

p/s: viết C++ rồi thì dùng fstream luôn.

Nguyễn Đăng Quang viết 10:51 ngày 01/10/2018

Tại vì mình đang tìm hiểu vấn đề đọc ghi file trong cả 2 thư viện. Nhưng cho minh hỏi là tại sao trong lần đọc bị lố ấy biên temp vẫn giữ giá trị là 1.6 ấy. Vì sau khi đọc giá trị 1.6 cuối cùng rồi, vì sau đó là khoảng trắng nên câu lệnh fscanf(fp,"%f", &temp) hay fp >> temp còn chạy thêm 1 lần nữa thì biến temp phải chứa giá trị Null hoặc một giá trị rác chứ sao lại vẫn giữ giá trị 1.6 ??

rogp10 viết 10:37 ngày 01/10/2018

Vì đọc không được (trong tr.hợp này, không có gì để đọc) nên mới không ghi vào đó bạn. Ghi rác thì dữ liệu banh ta lông luôn.

Nguyễn Đăng Quang viết 10:45 ngày 01/10/2018

ừm, tức là khoảng trắng không phải kiểu dữ liệu đọc được vào cho biến temp nên k làm thay đổi giá trị và tự nhiên sẽ thoát khỏi vòng lặp đúng kh. cảm ơn bạn.

Bài liên quan
0