0

拡張子が異なるベースファイル名に基づいて出力ファイルに名前を付けたいと思います。Cの疑似コード:

a_file = fopen(filename + ".dt1","wt");
b_file = fopen(filename + ".dt2","wt");
c_file = fopen(filename + ".dt3","wt");

を使用してこの例に従ってみstrncatましたが、プログラムはに追加し続けfilenameます。

f1=fopen(strcat(filename,".dt1"),"wt");
f2=fopen(strcat(filename,".dt2"),"wt");
f3=fopen(strcat(filename,".dt3"),"wt");

これは以下を出力します:

filename.dt1
filename.dt1.dt2
filename.dt1.dt2.dt3

最終結果は次のようになります。

filename.dt1
filename.dt2
filename.dt3
4

5 に答える 5

6

strcat指定された文字列に拡張子を追加することを考慮すると、コードは期待どおりに機能しています。使用している文字列は1つだけなので、拡張機能は互いに積み重ねられます。

これを行う1つの方法は、次の場合に単一の文字列を使用する投稿されたコードを修正することですfilename

size_t len = strlen(filename);
f1 = fopen(strcat(filename, ".dt1"), "wt");
filename[len] = '\0';
f2 = fopen(strcat(filename, ".dt2"), "wt");
filename[len] = '\0';
f3 = fopen(strcat(filename, ".dt3"), "wt");

このインデックスを設定すると、呼び出しの合間に元の文字列に\0効果的に切り捨てられます。filename

追加された拡張子(4文字の追加スペース)を含めるのに十分な大きさであるfilename 必要があります。これを行うと、各ファイルを開いた後に中間ファイル名が失われることに注意してください。

または、拡張子が最後の文字のみで異なる場合:

size_t len = 0;
f1 = fopen(strcat(filename, ".dt1"), "wt");
len = strlen(filename);
filename[len - 1] = '2';
f2 = fopen(filename), "wt");
filename[len - 1] = '3';
f3 = fopen(filename, "wt");

上記と同じ注意事項が適用されます。

于 2012-08-06T21:20:34.970 に答える
6

これstrcatは、最初の文字列のバッファに直接書き込むためです。

最も簡単な方法は、おそらくsnprintf2つの文字列を結合するために使用することです。

snprintf(filename_a, n+4, "%s.dt1", filename);
snprintf(filename_b, n+4, "%s.dt2", filename);
snprintf(filename_c, n+4, "%s.dt3", filename);

ここで、filenameは長さn(末尾を含む\0)、および、filename_aは少なくとも長さのバッファーです。filename_bfilename_cn+4

(を使用することもできますがsprintf、常に注意することをお勧めします。)

于 2012-08-06T21:21:34.877 に答える
2

私が言うあなたのかなり合理的な出力:

char * strcat ( char * destination, const char * source );

ソース文字列のコピーを宛先文字列に追加します。宛先の終了ヌル文字はソースの最初の文字で上書きされ、宛先の両方の連結によって形成された新しい文字列の最後に新しいヌル文字が追加されます。

したがって、が指す文字配列は、連結結果filenameから返されstrcat、連結結果で変更されます。

非常に簡単な修正は、変更する前にファイル名の長さを覚えてから、次のことを行うことです。

filename[filename_length_before_modification] = '\0';

これにより、追加された拡張機能が効果的にカットされ、開始点に戻ります。

于 2012-08-06T21:21:39.560 に答える
2

標準のCライブラリにはちょっとした苦痛がありますが、これは私が行う方法です。

    char *fn = malloc(strlen(filename+5)); // Allocate a string with enough space
                                           // for the extensions.

    sprintf(fn, "%s.dt1", filename);       // Copy the name with extensions into fn.
    a_file = fopen(fn,"wt");               //
    sprintf(fn, "%s.dt2", filename);       //
    b_file = fopen(fn,"wt");               //
    sprintf(fn, "%s.dt3", filename);       //
    c_file = fopen(fn,"wt");               //

    free(fn); // Free the memory gained from malloc.
于 2012-08-06T21:26:03.390 に答える
1

より効率的な方法。毎回拡張子をコピーするだけです。最後の文字だけが変更されると仮定すると、さらに効率的にすることができます(pb2qの2番目のソリューションを参照)。

(テストされていない、おそらく1つオフ)

size_t len = strlen(filename);
char *buf = malloc(len+4); // Allocate a string with enough space for the
                           // extensions.
strcpy(buf, filename);
char *ext = buf+len // Get a pointer to where the extension starts.

strcpy(ext, ".dt1");             // Copy the name with extensions into fn.
FILE *a_file = fopen(buf, "wt"); //
strcpy(ext, ".dt2");             // 
FILE *b_file = fopen(buf, "wt"); //
strcpy(ext, ".dt3");             // 
FILE *c_file = fopen(buf, "wt"); //

free(buf); // Free the memory gained from malloc.
于 2012-08-07T02:50:51.240 に答える