2010-01-05 13 views
11

Desidero riscrivere il comando "cp" di Linux. Quindi questo programma funzionerà come #./a.out originalfile copiedfile. Posso aprire il file, creare un nuovo file ma non posso scrivere il nuovo file. Niente è scritto. Quale potrebbe essere la ragione?Come scrivere un file con C in Linux?

Il codice C corrente è:

#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

Variabile non utilizzata fd2; non dimenticare di controllare che la scrittura scriva tutto ciò che ti aspettavi; non usare assegnazioni come condizioni (usa GCC -Wall); è ancora meglio restituire un valore da main() sebbene C99 (erroneamente) permetta di lasciare il return off main(). Il tuo messaggio di errore per fd1 non è corretto; non esci quando fallisce su fd1. È possibile utilizzare sizeof (buffer) nella lettura anziché 50, che è la metà della dimensione del buffer. Gli errori sono scritti in modo classico su stderr, non su stdout. Il tuo loop si imbatte in problemi se la lettura fallisce (valore negativo) anziché restituire nulla. –

+0

Ho appena copiato e incollato il codice sulla mia macchina, compilato con gcc e funziona perfettamente. – Dipstick

+0

Oh, è successo qualcosa di miracoloso.A causa del tuo commento, ho provato a spostare il file in un altro posto e a testarlo di nuovo. Funziona!!! Grazie mille. – Devyn

risposta

12

è necessario scrivere() read() i dati nel nuovo file:

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); 

Aggiornamento: aggiunto apre il corretto ...

Btw, l'O_CREAT può essere in OR (O_CREAT | O_WRONLY). In realtà stai aprendo troppi handle di file. Basta aprire una volta.

+0

Ciao, grazie per la risposta. Ho modificato il mio post con un nuovo codice. Ho provato come hai detto, ma ancora non funziona. Nulla è scritto nel nuovo file. Mi aiuti per favore! – Devyn

+0

Aggiornato il mio post, si spera che sia un po 'meglio ... – dlamotte

+0

Mi dispiace, ma ancora non funziona. Ho messo una stringa all'interno del ciclo while e ha dimostrato che il ciclo si è svolto solo una volta. :( – Devyn

2

devi fare write nello stesso ciclo come read.

7

Prima di tutto, il codice che hai scritto non è portabile, anche se lo fai funzionare. Perché utilizzare le funzioni specifiche del sistema operativo quando esiste un modo perfettamente indipendente dalla piattaforma per farlo? Ecco una versione che utilizza solo un singolo file di intestazione ed è portabile su qualsiasi piattaforma che implementa la libreria standard 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: Il glibc reference ha questo da dire:

In generale, si dovrebbe bastone con utilizzando flussi piuttosto che archiviare descrittori, a meno che non ci sia qualche specifica operazione che si vuole fare che può essere eseguito solo su un descrittore di file. Se sei un programmatore di inizio e non sono sicuro di quali funzioni da utilizzare, si consigliamo di concentrarsi sulle funzioni di ingresso formattati (vedere Input formattato) e formattati uscita funzioni (vedi output formattato).

Se siete preoccupati per la portabilità dei vostri programmi per sistemi diversi GNU, si dovrebbe anche essere consapevoli che descrittori di file non sono più portabile come flussi. Ci si può aspettare qualsiasi sistema esecuzione ISO C di sostenere i flussi, ma sistemi non-GNU potrebbe non supportare i file descrittori a tutti, o può solo implementare un sottoinsieme delle GNU funzioni che operano su file di descrittori. La maggior parte delle funzioni del descrittore di file nella libreria GNU sono incluse nello standard POSIX.1 , tuttavia.

+0

Sarei interessato al feed di nuovo sul motivo per cui ho ottenuto un downvot su questo ... –

+0

Penso che tu faccia un buon punto sull'uso degli stream ... (Non ti ho votato), ma ti annullerò a zero. – dlamotte

+0

Il down down in sé non mi disturba affatto, è il _why_ a cui sono interessato. Il feedback, sia positivo che negativo, mi aiuta a migliorare me stesso. Se posso farlo mentre (si spera) aiutando qualcun altro allo stesso tempo, niente del genere. –