Code C đổi địa chỉ ảo thành địa chỉ vật lý chạy thành công trên Win nhưng chạy bị lặp trên Ubuntu

Em có bài tập về đổi địa chỉ ảo thành địa chỉ vật lý, em đã chạy thành công trên win nhưng khi đưa code và Ubuntu thì nó lại bị lập ở dòng cuối cùng (“Can not find the physical address of 1751”) @@. Mọi người có thể giải thích với em nguyên nhân được không ạ.

#include <stdio.h>
#include <malloc.h>
#include <math.h>

void translate_physical_address( long dec, long index[] ){
	long integer_part, remainder_part, dec_physical_address;
	
	integer_part   = dec / 128;
	remainder_part = dec % 128;
	
	if (integer_part >= 0 && integer_part <= 6){
		dec_physical_address = index[integer_part] * 128 + remainder_part;
		printf("Physical address of %ld: %ld\n", dec, dec_physical_address);
			
	}else
		printf("Can not find the physical address of %ld\n", dec);
}
int main() {
long dec, index[7] = { 6, 5, 4, 2, 7, 3, 1 };
	FILE *f;
	char filename[20];
	
	printf("Enter the name of file: ");
	scanf("%s",filename);
	
	f = fopen(filename, "r");
	while (!feof(f)){
		fscanf(f, "%ld", &dec);
		translate_physical_address(dec, index);
	} 
return 0; 
}

Screenshot 2021-05-12 165000
Kết quả khi chạy trên win


Kết quả khi chạy trên linux

1 Like

Trường hợp else của bạn thử print ra kiểu của integer_part và integer_part xem liệu nó có phải là integer không hay là kiểu gì khác? Có khả năng nó là cái gì đó khác nên vế else đã bắt hết.

Bạn có để ý là dòng cuối cùng gây ra sự việc chứ không phải con số? Khả năng là do file của bạn khi save trên Windows thì ký tự xuống dòng là CR LF trong khi trong Ubuntu thì chỉ là LF. Dẫn đến, bài này có khả năng là câu trả lời cho việc đọc file gây ra như bạn đang thấy.

4 Likes

Anh/chị giải thích rất hợp lý ạ nhưng có thể chỉ cách khắc phục được không ạ@@?

Em đã thử in ra số dec,integer_part,remainder_part và kết quả là như bên dưới
Screenshot 2021-05-12 175446

Bạn tạo file text giống hệt nội dung bên Windows bằng trình soạn thảo văn bản thô trên Ubuntu thử nhé (như nano, gEdit). Nếu chạy với file đó mà OK thì đích thị là do ký tự xuống dòng trong file text, còn nếu nó vẫn bị như cũ thì lại post lên đây vấn đề để người khác xem xét thử.

3 Likes

Em đã tạo 1 file a bằng trình soạn thảo gedit chỉ chứa 1 dòng “872”. Khi chạy thì nó vẫn bị lập ạ. Em nghĩ vấn đề là dò while(!feof(f)) có vấn đề khi nó chạy đến dòng cuối cùng của file.
Screenshot 2021-05-12 181334

Do feof trả về kết quả của lần đọc trước nên tới lần đọc áp chót vẫn đọc đúng, còn lần đọc cuối cùng không thu được gì cả.

3 Likes

Thế thì mình phải sửa như thế nào vậy ạ? Em vẫn thắc mắc là lúc chạy trên win chạy thì đúng mà chạy trên ubuntu lại [email protected]@

Mình không biết C, không biết nếu bỏ dùng feof và chỉ dùng fscanf thì sao không nhỉ?

while (fscanf(f, "%ld", &dec) == 1) {
	translate_physical_address(dec, index);
} 
5 Likes

Cảm ơn bạn nhiều lắm!!! Dù mình vẫn thắc mắc lại sao cùng 1 dòng code không thể chạy trên 2 hệ nhưng giải pháp của bạn đúng rồi.

Do cấu trúc file text trên Linux và Windows khác nhau đó bạn.

2 Likes

Thế mới có khái niệm là cross-platform được đẻ ra cho mấy ông lập trình xoắn não chơi. Giả sử chỉ cần viết code đơn thuần thôi rồi mang qua hệ điều hành nào cũng chạy thì mấy ông lập trình xem ra nhàn nhã quá :smiley:

1 Like

Có thể file text bên Linux dư 1 dòng cuối.
Code đúng phải là

	while (!feof(f)){
		if (fscanf(f, "%ld", &dec) > 0){
		  translate_physical_address(dec, index);
        }
	}

Good practice là luôn luôn phải kiểm tra kết quả trả về nếu hàm có trả về error.
Ngày trước mình thường mặc định ptr = (int*) malloc(100 * sizeof(int)); luôn malloc được. Nhưng thực tế gặp nhiều lần không được mới đổi suy nghĩ.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?