2010-12-10 11 views
0

ユーザはコマンドラインでいくつかのファイル名を入力する必要があり、プログラムは各ファイル名をargv[]配列から読み込みます。cファイルへのread()とwrite()の内容のプログラミング

それぞれのファイル名を読みたいと思います。たとえば、argv [2]が 'myfile.txt'の場合、プログラムは 'myfile.txt'の内容を読み込み、値をchar buffer[BUFSIZ]に格納し、別のファイルにbufferの内容を書き込む必要があります。

ただし、コンテンツが書き込まれる前に、プログラムはファイルの名前とサイズも書き込む必要があります。そのようなファイルは後で容易に抽出することができる。 tarのようなビット。私はどのように私の質問は

1である

myfile.txt256Thisisfilecontentmyfile2.txt156Thisisfile2content.............. 

ように私は、ユーザーが追加したファイルの数に応じて、bufferの内容を記述したファイルは、文字列でなければなりませんwrite()文を使用して、argv[2]の値をファイルに書き込みます。文字配列の書き込みに問題があるため、write()内にsizeof(?)を入れるとどうなりますか?ユーザーが入力したファイル名の長さが分からないため、以下を参照してください。

2) Iが「&」は、例えば、名前の後にファイルに整数値を書き込むために使用していますが、ファイル

のサイズのファイル名の後に4つのバイトを書き込むここに私が書いたコードは、あります

char buffer[BUFSIZ]; 
int numfiles=5; //say this is no of files user entered at command 
open(file..... 

lseek(fdout, 0, SEEK_SET); //start begging of file and move along each file some for loop 

for(i=0-; ...... 
//for each file write filename,filesize,data....filename,filesize,data...... 
int bytesread=read(argv[i],buffer,sizeof(buffer)); 
write(outputfile, argv[i], sizeof(argv)); //write filename size of enough to store value of filename 
write(outputfile, &bytesread, sizeof(bytesread)); 
write(outputfile, buffer, sizeof(buffer)); 

しかし、コードは期待通りに機能しません。

提案がありますか?

+0

解決済みの場合は、タグを更新してください。 – ruslik

+0

fwrite()ではなくopen()とfwrite()ではなくwrite()を使用しているのはなぜですか? – AlastairG

答えて

2

argvがnullで終わる配列で構成されているので、あなたが書くことができる長さは引数とヌルターミネータの両方を書くことstrlen(argv[2])+1です:

また
size_t sz = strlen (argv[2]); 
write (fd, argv[2], sz + 1); 

、あなたは文字が続く長さが必要な場合は、することができますsize_t自体がstrlenから返され、その後にその多くの文字が続きます。

size_t sz = strlen (argv[2]); 
write (fd, &sz, sizeof (size_t)); 
write (fd, argv[2], sz); 

また、次のファイルを読み取るときに、ファイルの長さも書き込む必要があります。

0

1.、あなたが文字列に次のように書くことができます、しかしそれは、この単純ではない、ほとんどの時間

size_t size = strlen(string); 
write(fd, string, size); 

を:あなたはどのくらい知っていますので、あなたが文字列のサイズが必要になりますが読む必要があります。だから、文字列のサイズも書きます。

2、整数は次のように書くことができます。

write(fd, &integer, sizeof(integer)); 

これは簡単ですが、あなたは異なるアーキテクチャー上のファイルを使用する予定がある場合、あなたはあまりにもエンディアンに対処する必要があります。

0

バイナリ形式を使用するのが最善の方法です。あなたの例では、内容の長さが256であるmyfile.txtというファイル、または内容の長さが56であるmyfile.txt2、または内容の長さが6のmyfile.txt25というファイルがありますか?ファイル名の終わりとコンテンツ長フィールドの開始を区別する方法はありません。同様に、コンテンツの長さの終わりとコンテンツの開始を区別する方法はありません。テキスト形式を使用する必要がある場合は、固定幅のフィールドがこれを助けます。私。ファイル名は32文字、コンテンツ長は6桁です。しかしバイナリ形式がより効率的です。

strlen()を使用してファイル名の長さを取得しますが、完全に間違った結果になるので、sizeof(argv)は使用しないでください。 sizeof(argv[i])も間違った結果を与えます。

ファイル名の長さを4バイト、ファイル名を4バイト、内容の長さを4バイト、内容を続けて書きます。

フォーマットを移植可能にする場合は、バイトオーダーの問題に注意する必要があります。

最後に、ファイルがバッファにすべて収まらない場合、あなたは詰め込まれます。読み込み中のファイルのサイズを取得して出力ファイルに書き込む必要があります。次に、最初のファイルから2番目のファイルにそのバイト数を読み込む必要があります。これを行うにはさまざまな方法があります。回答の男性のための

0

おかげで、

は私が)ので、私は(読み込むバイトの正確な値を知っているうちは(size_t)の構造だけではなく、割り当てられた(int)を使用しないことを決定し、(文字)タイプ。つまり、私はファイルの先頭から始まり、4バイト(int)を読み込み、ファイル名の長さの値を取得します。次のread()でサイズとして使用します。

したがって、 )ユーザーは、ちょうどここでそれを読みやすくするために、明らかにスペースを入れず、私は長い文字列に書き込む出力ファイル(コピーされたファイル)にファイルを入力

filenamesizeファイル名filecontentsize含むFileContent すなわち10 myfile.txtの5ハロー

ので、そのデータを読み出すには、lseek()を使用してファイルの先頭から始め、最初の4バイトが(int)ファイル名の長さであることを知っています。関数。

私の問題は、ファイル名を正しい長さで格納するように配列を宣言するために、その値をfilenamesize(最初の4バイト)に読み込むことです。どのように私は(読み取りにこの配列を置く)が指定されたchar配列内の読み取りを格納値か、下記を参照してください

int namelen; //value read from first 4 bytes of file lenght of filename to go in nxt read() 
char filename[namelen]; 
read(fd, filename[namelen], namelen);//filename should have 'myfile.txt' if user entered that filename 

私が保存された私に、ファイル名のな長さを与えるファイルから最初の4バイトという読み一度だから私の質問ですnamelenでは、元のファイルのファイル名を与えるためにnamelen量のバイトを読み込み、ディレクトリ内にコピーされたファイルを作成することができますか?

ありがとうございました

関連する問題