質問
私は、Linux GCCのC99を使用しています。
私は、最高の技術がどうなるか疑問に思って。文字列を変更します。私ははstrstr()を使用しています。
私は「file.vce」と呼ばれるファイル名を持っていると私は、「file.wav」に拡張子を変更したい。
これが最善の方法です。
char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);
何かアドバイスのための多くのおかげで、
<時間>私はあなたの提案を使用して使用して私の答えを編集しました。あなたは間違って何かを見ることはできますか?
/** Replace the file extension .vce with .wav */
void replace_file_extension(char *file_name)
{
char *p_extension;
/** Find the extension .vce */
p_extension = strrchr(file_name, '.');
if(p_extension)
{
strcpy(++p_extension, "wav");
}
else
{
/** Filename did not have the .vce extension */
/** Display debug information */
}
}
int main(void)
{
char filename[80] = "filename.vce";
replace_file_extension(filename);
printf("filename: %s\n", filename);
return 0;
}
解決
私はこれを行うだろう。
char file_name[80] = "filename.vce";
char *pExt;
pExt = strrchr(file_name, ".");
if( pExt )
strcpy(++pExt, "wav");
else
{
// hey no extension
}
printf("file name: %s\n", file_name);
あなたはすべてのCプログラムでポインタ操作を行う必要があります。もちろん、あなたは、いくつかのより多くの実行などの上にバッファをチェックするんだろうかさえパス特定の機能を使用します。
他のヒント
を持ついくつかの問題があります。
char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);
があり、1つの文字列のためのストレージのみですが、最後に次の2つの異なる文字列を印刷しようとします。
new_file_name
という名前の変数には、実際には同じファイル名の一部を指します。
の文字列のVCEは、ファイル名だけではなく、拡張内のどこにでも発生する可能性があります。ファイル名はsrvce.vce
何でしたか?
あなたはおそらく最後を見つけたいです。文字列内の文字は、それが予想される拡張子が続いているかどうかを確認し、その拡張子を交換してください。そして、あなたは、元のバッファを変更することによって、これを行うならば、あなたはその後、古い文字列を印刷することができませんことを覚えています。
というよりも検索します。またはVCEのいずれかのうち、文字列内に複数回現れる文字列の長さを計算し、拡張する点に3を引くことができます。 strncpyをを使用してインプレースの拡張を交換してください。
size_t length;
char* pextension;
char file_name[80] = "filename.vce";
printf("file name: %s\n", file_name);
length = strlen(file_name);
pextension = file_name + length - 3;
strncpy(pextension, "wav", 3);
printf("new file name: %s\n", file_name);
あなたはあなたのケースでnew_file_name
がそれを追加しませんので、手動でstrncpy()
の終わりにゼロターミネータを追加する必要があります。
ちょうどあなたがすでに適切な場所でゼロバイトを持っていることが起こったが、
のようなものを行うには良い習慣ですので、それはすべての状況で保証することはできませんnew_file_name[3] = '\0';
後strncpy()
ます。
また、文字列 "VCE" は、ファイル名の内側に表示されることがあり注意します。
あなたのコードを持ついくつかの問題があります。ここで別のテイクは、の変更がインラインコメントでます:
char file_name[80] = "filename.vce";
char *new_file_name = NULL;
printf("old file name: '%s'\n", file_name);
/* Use strrstr(), to find the last occurance, and include the period. */
new_file_name = strrstr(file_name, ".vce");
if(new_file_name != NULL)
{
/* Use plain strcpy() to make sure the terminator gets there.
* Don't forget the period.
*/
strcpy(new_file_name, ".wav");
}
printf("new file name: '%s'\n", file_name);
このはまだ改善することができ、それは例えば、新しい拡張子を含めるための十分な余地があることを確認していません。しかし、それは単一の文字で突っついよりslighlyより自然な形で、文字列を終了します。
私は退屈だし、代わりに元のコードで問題を指摘し、私は自分自身を書きました。私は有益な目的のためにそれを明確に維持しようとします。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Replace the last suffix in a filename with a new suffix. Copy the new
name to a new string, allocated with malloc. Return new string.
Caller MUST free new string.
If old name has no suffix, a period and the new suffix is appended
to it. The new suffix MUST include a period it one is desired.
Slashes are interepreted to separate directories in the filename.
Suffixes are only looked after the last slash, if any.
*/
char *replace_filename_suffix(const char *pathname, const char *new_suffix)
{
size_t new_size;
size_t pathname_len;
size_t suffix_len;
size_t before_suffix;
char *last_slash;
char *last_period;
char *new_name;
/* Allocate enough memory for the resulting string. We allocate enough
for the worst case, for simplicity. */
pathname_len = strlen(pathname);
suffix_len = strlen(new_suffix);
new_size = pathname_len + suffix_len + 1;
new_name = malloc(new_size);
if (new_name == NULL)
return NULL;
/* Compute the number of characters to copy from the old name. */
last_slash = strrchr(pathname, '/');
last_period = strrchr(pathname, '.');
if (last_period && (!last_slash || last_period > last_slash))
before_suffix = last_period - pathname;
else
before_suffix = pathname_len;
/* Copy over the stuff before the old suffix. Then append a period
and the new suffix. */
#if USE_SPRINTF
/* This uses snprintf, which is how I would normally do this. The
%.*s formatting directive is used to copy a specific amount
of text from pathname. Note that this has the theoretical
problem with filenames larger than will fit into an integer. */
snprintf(new_name, new_size, "%.*s%s", (int) before_suffix, pathname,
new_suffix);
#else
/* This uses memcpy and strcpy, to demonstrate how they might be
used instead. Much C string processing needs to be done with
these low-level tools. */
memcpy(new_name, pathname, before_suffix);
strcpy(new_name + before_suffix, new_suffix);
#endif
/* All done. */
return new_name;
}
int main(int argc, char **argv)
{
int i;
char *new_name;
for (i = 1; i + 1 < argc; ++i) {
new_name = replace_filename_suffix(argv[i], argv[i+1]);
if (new_name == NULL) {
perror("replace_filename_suffix");
return EXIT_FAILURE;
}
printf("original: %s\nsuffix: %s\nnew name: %s\n",
argv[i], argv[i+1], new_name);
free(new_name);
}
return 0;
}