2

現在、次のコマンドを使用して、プログラムの出力ファイルに書き込みます。2D配列に格納されている文字列を取得して、設定した出力ファイル「url_storage.txt」に書き込みたいと思います。

以下の例は、プログラムの開始近くでファイルを設定する方法(つまり、最初のファイル記述子宣言とopen(...)の呼び出し)を示し、write(...)のプライマリ呼び出しを示しています。 whileループ(2D配列の各スロットからの書き込み、または文字列/文字配列のコレクション)。私の問題は、各文字列の後にNEWLINE文字を挿入したいのですが、次のコードでは、各文字列(または各書き込みの結果)が別々の行にあるファイルは生成されません。書き込み関数が改行文字に準拠するようにしたいことを認識する簡単な方法はありますか?また、ファイル位置ポインタを調整する関数lseek(...)があることもわかりました(新しい行の調整にはあまり役立たないようです)。次の行を指すようにそれを取得する方法についての提案はありますか?

int fd2 = open("/directory/path/to/target/output/file/url_storage.txt", O_WRONLY, O_CREAT, 00777);

...
while(...){
      ...
      (void) write(fd2, (" %s \n", matches[ind]), strlen(matches[ind]));
}
4

1 に答える 1

4

これ:

write(fd2, (" %s \n", matches[ind]), strlen(matches[ind]));

あなたが思っていることをしません。と混同printf()していwrite()ます。「フォーマット文字列」" %s \n"はコンマ式の最初の部分であり、事実上破棄されます。文字列だけがファイルに書き込まれます。改行を個別に記述する必要があります。

if (write(fd2, " ", 1) != 1 ||
    write(fd2, matches[ind], strlen(matches[ind])) != strlen(matches[ind]) ||
    write(fd2, " \n", 2) != 2)
    ...something went wrong...

または、ファイル ストリームの代わりにファイル ディスクリプタに書き込みますが、dprintf()それに似ているPOSIX の使用を検討してください。fprintf()

if (dprintf(fd2, " %s \n", matches[ind]) != strlen(matches[ind])+3)
    ...something went wrong...

文字列の前後にスペースを追加して、あなたの意図と思われるものに従おうとしましたが、それが私のコードであれば、少なくとも末尾のスペースは省略されます (ほとんどの場合、改行の前にスペースは必要ありません —ただし、電子メールの署名の開始を示す の後を除き--ます. 先行するスペースは、文字列をその前にあるものから分離するために必要かもしれません. しかし、私はおそらく次のように書きます:

if (dprintf(fd2, "%s\n", matches[ind]) != strlen(matches[ind])+1)
    ...something went wrong...

write()または、個別の呼び出しと同等です。


ちなみに、あなたは次のようなものを書きました:

 const char path[] = "/directory/path/to/target/output/file/url_storage.txt";
 int fd2 = open(path, O_WRONLY, O_CREAT, 00777);

複雑な歴史的理由により、 のプロトタイプはopen()ですがint open(const char *path, int flag, ...);、有効な引数は 2 つまたは 3 つだけであり、4 を使用しています。

 int fd2 = open(path, O_WRONLY|O_CREAT, 0777);

しかし、コンパイラは間違いをすぐに診断できません。結局、プロトタイプは「任意の数の引数」と言っています。また、シェル スクリプトを作成している場合を除き、ファイルは実行可能であってはなりません (したがって、0777 ではなく 0666 です)。公開で書き込み可能であってはならないと私は主張したいと思います。したがって、0664 または 0644 の方がよいでしょう、umask値の可用性にもかかわらず。ちなみに、リテラルの代わりに変数 like を使用する利点の 1 つpathは、文字列リテラルを繰り返す必要がない場合、ファイル名を使用して意味のあるエラー メッセージを簡単に報告できることです。

于 2013-03-14T04:19:52.200 に答える