2012-11-25 29 views
14

Là một phần của một bài tập từ một trong các lớp học của tôi, tôi phải viết một chương trình trong C để nhân đôi kết quả của lệnh ls -al. Tôi đã đọc về các tài liệu cần thiết nhưng tôi vẫn chưa nhận được kết quả đúng. Đây là mã của tôi cho đến nay, nó chỉ có nghĩa vụ để in ra kích thước tập tin và tên tập tin, nhưng kích thước tập tin in ấn của nó là không chính xác.Thực hiện lệnh ls -al trong C

Code:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 

int main(int argc, char* argv[]) 
{ 
    DIR *mydir; 
    struct dirent *myfile; 
    struct stat mystat; 

    mydir = opendir(argv[1]); 
    while((myfile = readdir(mydir)) != NULL) 
    { 
     stat(myfile->d_name, &mystat);  
     printf("%d",mystat.st_size); 
     printf(" %s\n", myfile->d_name); 
    } 
    closedir(mydir); 
} 

Đây là kết quả của tôi sau khi thực hiện mã:

[[email protected] ~]# ./a.out Downloads 
4096 .. 
4096 hw22.c 
4096 ankur.txt 
4096 . 
4096 destination.txt 

Dưới đây là các kích thước chính xác:

[[email protected] ~]# ls -al Downloads 
total 20 
drwxr-xr-x. 2 root root 4096 Nov 26 01:35 . 
dr-xr-x---. 24 root root 4096 Nov 26 01:29 .. 
-rw-r--r--. 1 root root 27 Nov 21 06:32 ankur.txt 
-rw-r--r--. 1 root root 38 Nov 21 06:50 destination.txt 
-rw-r--r--. 1 root root 1139 Nov 25 23:38 hw22.c 

bất cứ ai có thể vui lòng chỉ ra sai lầm của tôi.

Cảm ơn,

Ankur

+2

Làm việc tốt cho tôi. Kiểm tra giá trị trả về của stat() để xem có lỗi hay không. – Neal

+1

Hoạt động tốt ở đây. Giới thiệu kiểm tra lỗi cho mọi thứ (opendir(), readdir(), stat()). –

+0

Hoạt động tốt nếu bạn chạy nó trên '.', nhưng không phải nếu bạn cung cấp cho nó một thư mục khác. –

Trả lời

13

myfile->d_name là tên tập tin không phải là con đường, vì vậy bạn cần phải thêm tên file vào thư mục "Downloads/file.txt" đầu tiên, nếu nó không phải là thư mục làm việc:

char buf[512];  
while((myfile = readdir(mydir)) != NULL) 
{ 
    sprintf(buf, "%s/%s", argv[1], myfile->d_name); 
    stat(buf, &mystat); 
.... 

Là tại sao nó in 4096 đó là kích thước của các liên kết ... từ cuộc gọi cuối cùng đến stat().

Lưu ý: bạn nên phân bổ một bộ đệm đủ lớn để chứa tên thư mục, tập tin đặt tên cho NULL byte và các separator, một cái gì đó như thế này

strlen(argv[1]) + NAME_MAX + 2; 
+0

Cảm ơn bạn rất nhiều vì phản hồi của bạn, làm cho các bổ sung được đề xuất của bạn hoạt động. Chương trình đang cung cấp các kích thước tệp chính xác ngay bây giờ. Cảm ơn. – ankur3000

+0

@ ankur3000 bạn được chào đón, cũng kiểm tra ghi chú tôi đã thêm. – iabdalkader

+0

Điều này là không thể tin được hữu ích khi làm các giấy tờ hệ điều hành của tôi mà tôi cần thiết để cài đặt trình điều khiển trong hạt nhân 2.6.39 thi đua với qemu và chỉ một init .. Tôi vẫn không tìm ra somethings nhưng cảm ơn !! haha !! –

0

Vấn đề là khi bạn stat("ankur.txt", &mystat), bạn không làm việc trên các tập tin "Downloads/ankur.txt". Nhiều khả năng, số stat() không thành công; cách khác, nó đang báo cáo trên một tệp khác.

Do đó, bạn cần phải xem liệu hệ thống của mình có hỗ trợ fstatat() - mới trong POSIX 2008 hay sắp xếp để đặt trước tên của tệp có tên của thư mục.

1

Tôi tin rằng bạn sẽ quan sát rằng nếu bạn ./a.out . bạn sẽ nhận được hành vi mà bạn mong đợi.

Bạn có một lỗi hơi tinh tế, có thể quan sát được nếu bạn kiểm tra mã trả lại của cuộc gọi đến stat(2).

Sai lầm cơ bản: số dirent s được trả lại bởi readdir(2) (số myfile trong mã của bạn) sẽ có d_name liên quan đến mydir. mã của bạn sẽ stat.. đầu tiên, thành công, và vì vậy mystat sẽ chứa dữ liệu hợp lệ cho .., sau đó tất cả các cuộc gọi tiếp theo để stat(2) sẽ thất bại, trở về -1, mà bạn không kiểm tra, vì vậy mystat sẽ không được sửa đổi, và bạn sẽ in st_size cho giá trị cũ, tức là của ...

+0

Cảm ơn bạn đã trả lời, tôi thấy sự cố trong mã của tôi ngay bây giờ. Nhưng chính xác tại sao điều này lại xảy ra? Tôi nghĩ rằng khi chúng ta thực hiện lệnh opendir(), chương trình sẽ tự động điều chỉnh đường dẫn tệp cho thư mục đó. – ankur3000

-5

hoặc có thể chỉ hệ thống ("ls -al") cũng sẽ hoạt động!

+1

nó không trả lời câu hỏi cả. – Puriney

6

Đây là mã cuối cùng tôi phải làm việc cho bất kỳ ai quan tâm. Nó in kích thước tệp chính xác. Tín dụng đi đến người hỏi và mux để trả lời, chỉ cần đặt mã với nhau. Đầu vào tôi đã làm việc này là "./main." .

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 

int main(int argc, char* argv[]) 
{ 
    DIR *mydir; 
    struct dirent *myfile; 
    struct stat mystat; 

    char buf[512]; 
    mydir = opendir(argv[1]); 
    while((myfile = readdir(mydir)) != NULL) 
    { 
     sprintf(buf, "%s/%s", argv[1], myfile->d_name); 
     stat(buf, &mystat); 
     printf("%zu",mystat.st_size); 
     printf(" %s\n", myfile->d_name); 
    } 
    closedir(mydir); 
}