2010-01-05 35 views
11

Tôi muốn viết lại lệnh "cp" của Linux. Vì vậy, chương trình này sẽ hoạt động như #./a.out originalfile copiedfile. Tôi có thể mở tệp, tạo tệp mới nhưng không thể ghi tệp mới. Không có gì được viết. Điều gì có thể là lý do?Cách ghi tệp bằng C trong Linux?

Mã C hiện nay là:

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

int main(int argc,char *aa[]){ 
    int fd,fd1; 
    char buffer[100]; 

    if(argc!=3){ 
     printf("Usage : ./a.out <original> <copy> \n"); 
     return -1; 
    } 

    fd=open(aa[1],O_RDONLY,S_IRUSR); 
    if(fd==-1){ 
     printf("file not found.\n"); 
     return -1; 
    } 
    fd1=open(aa[2],O_CREAT | O_WRONLY,S_IRUSR); 
    if(fd1!=-1){ 
     printf("file is created.\n"); 
    } 
    ssize_t n; 
    while(n=read(fd,buffer,50)){ 
     write(fd1,buffer,n); 
     printf("..writing..\n"); 
    } 
    close(fd); 
    close(fd1); 
} 
+1

Biến không sử dụng fd2; đừng quên kiểm tra xem viết có viết mọi thứ bạn mong đợi không; không sử dụng các bài tập làm điều kiện (sử dụng GCC -Wall); nó vẫn còn tốt hơn để trả về một giá trị từ main() mặc dù C99 (nhầm lẫn) cho phép bạn rời khỏi return(). Thông báo lỗi của bạn cho fd1 không chính xác; bạn không thoát ra khi nó thất bại trên fd1. Bạn có thể sử dụng sizeof (buffer) trong phần đọc thay vì 50, bằng một nửa kích thước của bộ đệm của bạn. Lỗi được viết theo kiểu cổ điển đối với stderr, chứ không phải stdout. Vòng lặp của bạn chạy vào các vấn đề nếu đọc không thành công (giá trị âm) thay vì trả về không có gì. –

+0

Chỉ cần sao chép và dán mã của bạn vào máy của tôi, được biên dịch bằng gcc và nó hoạt động tốt. – Dipstick

+0

Ồ, điều kỳ diệu đã xảy ra.Vì nhận xét của bạn, tôi đã cố di chuyển tệp đến một địa điểm khác và được kiểm tra lại. Nó hoạt động !!! Cảm ơn bạn rất nhiều. – Devyn

Trả lời

12

Bạn cần phải viết() đọc() dữ liệu vào tập tin mới:

ssize_t nrd; 
int fd; 
int fd1; 

fd = open(aa[1], O_RDONLY); 
fd1 = open(aa[2], O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 
while (nrd = read(fd,buffer,50)) { 
    write(fd1,buffer,nrd); 
} 

close(fd); 
close(fd1); 

Cập nhật: thêm thích hợp mở ...

Btw, các O_CREAT có thể được OR'd (O_CREAT | O_WRONLY). Bạn đang thực sự mở quá nhiều tệp xử lý. Chỉ cần mở một lần.

+0

Xin chào, cảm ơn bạn đã trả lời. Tôi đã chỉnh sửa bài đăng của mình bằng mã mới. Tôi đã cố gắng như bạn nói nhưng vẫn không hoạt động. Không có gì được ghi vào tệp mới. Làm ơn giúp tôi! – Devyn

+0

Đã cập nhật bài đăng của tôi, hy vọng điều đó tốt hơn một chút ... – dlamotte

+0

Tôi xin lỗi nhưng vẫn không hoạt động. Tôi đặt một số chuỗi bên trong vòng lặp while và nó cho thấy rằng trong khi vòng lặp làm việc chỉ một lần. :( – Devyn

2

Bạn phải làm write trong vòng lặp giống như read.

7

Trước hết, mã bạn viết không phải là di động, ngay cả khi bạn làm cho mã hoạt động. Tại sao lại sử dụng các chức năng dành riêng cho hệ điều hành khi có một cách hoàn toàn độc lập với nền tảng làm việc đó? Đây là một phiên bản chỉ sử dụng một tệp tiêu đề duy nhất và có thể di chuyển đến bất kỳ nền tảng nào thực hiện thư viện chuẩn C.

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    FILE* sourceFile; 
    FILE* destFile; 
    char buf[50]; 
    int numBytes; 

    if(argc!=3) 
    { 
     printf("Usage: fcopy source destination\n"); 
     return 1; 
    } 

    sourceFile = fopen(argv[1], "rb"); 
    destFile = fopen(argv[2], "wb"); 

    if(sourceFile==NULL) 
    { 
     printf("Could not open source file\n"); 
     return 2; 
    } 
    if(destFile==NULL) 
    { 
     printf("Could not open destination file\n"); 
     return 3; 
    } 

    while(numBytes=fread(buf, 1, 50, sourceFile)) 
    { 
     fwrite(buf, 1, numBytes, destFile); 
    } 

    fclose(sourceFile); 
    fclose(destFile); 

    return 0; 
} 

EDIT: Các glibc reference đã cho biết:

Nói chung, bạn nên gắn bó với sử dụng suối chứ không phải nộp mô tả, trừ khi có một số hoạt động cụ thể mà bạn muốn làm điều đó chỉ có thể được thực hiện trên bộ mô tả tệp. Nếu bạn là một lập trình viên mới bắt đầu và không chắc chắn những gì các chức năng sử dụng, chúng tôi đề nghị bạn nên tập trung vào các chức năng đầu vào định dạng (xem Input định dạng) và định dạng đầu ra chức năng (xem Output format).

Nếu bạn lo lắng về tính di động các chương trình của bạn với các hệ thống khác ngoài GNU, bạn cũng nên lưu ý rằng file descriptor không phải là di như suối. Bạn có thể mong đợi mọi hệ thống chạy ISO C để hỗ trợ luồng, nhưng hệ thống không phải GNU có thể không hỗ trợ tệp mô tả, hoặc chỉ có thể thực hiện một tập con của các chức năng . Hầu hết các tệp chức năng mô tả trong thư viện GNU được bao gồm trong tiêu chuẩn POSIX.1 , tuy nhiên.

+0

Tôi muốn được quan tâm đến nguồn cấp dữ liệu trở lại lý do tại sao chính xác tôi đã downvoted trên này ... –

+0

Tôi nghĩ rằng bạn làm cho một điểm tốt về việc sử dụng dòng ... (Tôi đã không xuống bầu bạn), nhưng tôi sẽ upvote bạn trở lại số không. – dlamotte

+0

Bản thân downvote không làm phiền tôi chút nào, đó là _why_ mà tôi quan tâm. Phản hồi, dù là tích cực hay tiêu cực, giúp tôi tự cải thiện bản thân mình. Nếu tôi có thể làm điều đó trong khi (hy vọng) giúp đỡ người khác cùng một lúc, không có gì giống như nó. –

Các vấn đề liên quan