C 更改字符串
我正在使用Linux GCC c99 我想知道什么是最好的技术。更改字符串。我正在使用strstr() 我有一个名为“file.vce”的文件名,我想把扩展名改为“file.wav” 这是最好的方法吗C 更改字符串,c,strstr,C,Strstr,我正在使用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("
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;
}
您必须在
new\u file\u name
的末尾手动添加零终止符,因为strncpy()
不会在您的案例中添加它
碰巧您在正确的位置已经有了零字节,但不能保证在所有情况下都有零字节,所以这样做是一个好习惯
new_file_name[3] = '\0';
在strncpy()之后
还要注意,字符串“vce”可能出现在文件名中。您必须手动在
新文件名的末尾添加零终止符,因为strncpy()
不会在您的案例中添加它
碰巧您在正确的位置已经有了零字节,但不能保证在所有情况下都有零字节,所以这样做是一个好习惯
new_file_name[3] = '\0';
在strncpy()之后
还要注意,字符串“vce”可能会出现在文件名中。以下方面存在一些问题:
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);
只有一个字符串的存储空间,但最后您尝试打印两个不同的字符串
名为new\u file\u name
的变量实际上指向同一文件名的一部分
字符串vce可能出现在文件名中的任何位置,而不仅仅是扩展名。如果文件名是srvce.vce
,该怎么办
你可能想找到最后一个。字符串中的字符,然后检查其后面是否跟有预期的扩展名,然后替换该扩展名。请记住,如果通过修改原始缓冲区来执行此操作,则以后将无法打印旧字符串。以下方面存在一些问题:
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);
只有一个字符串的存储空间,但最后您尝试打印两个不同的字符串
名为new\u file\u name
的变量实际上指向同一文件名的一部分
字符串vce可能出现在文件名中的任何位置,而不仅仅是扩展名。如果文件名是srvce.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);
这仍然可以改进,例如,它不会检查是否有足够的空间容纳新的扩展。但是它确实终止了字符串,这比戳单个字符更自然。您的代码有一些问题。下面是一个不同的例子,其中的更改以内联方式注释:
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);
这仍然可以改进,例如,它不会检查是否有足够的空间容纳新的扩展。但它确实终止了字符串,比戳单个字符更自然。我会这样做
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 *pExt;
pExt = strrchr(file_name, ".");
if( pExt )
strcpy(++pExt, "wav");
else
{
// hey no extension
}
printf("file name: %s\n", file_name);
您需要在每个c程序中进行指针操作。当然,您需要更多地检查缓冲区溢出等,甚至使用特定于路径的函数。而不是搜索。或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);
而不是寻找。或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);
我很无聊,我没有指出原始代码中的问题,而是编写了自己的代码。我尽量把它弄清楚,以供参考
#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;
}
#包括
#包括
#包括
/*用新后缀替换文件名中的最后一个后缀。复制新的
使用malloc分配的新字符串的名称。返回新字符串。
调用方必须释放新字符串。
如果旧名称没有后缀,则添加句点和新后缀
去吧。新后缀必须包含所需的句点。
斜杠在文件名中被分隔成不同的目录。
后缀仅在最后一个斜杠(如果有的话)之后查看。
*/
字符*替换文件名\后缀(常量字符*路径名,常量字符*新后缀)
{
尺寸\u t新尺寸;
大小\u t路径名\u len;
大小后缀长度;
后缀前的大小;
字符*最后一个斜杠;
字符*最后一个字符周期;
char*新的_名称;
/*为生成的字符串分配足够的内存
为了简单起见,在最坏的情况下*/
路径名=strlen(路径名);
后缀_len=strlen(新的_后缀);
新建大小=路径名长度+后缀长度+1;
新_名称=malloc(新_尺寸);
if(new_name==NULL)
返回NULL;
/*计算要从旧名称复制的字符数*/
last_slash=strrchr(路径名“/”);
last_period=strrchr(路径名“.”);
if(最后一段时间&(!最后一段斜杠| |最后一段时间>最后一段斜杠))
before\u suffix=最后一个\u时段-路径名;
其他的
在后缀=路径名之前;
/*复制旧后缀之前的内容。然后附加句号
还有新的后缀*/
#如果使用
/*这使用了snprintf,这是我通常的做法
%*s formatting指令用于复制特定数量
来自路径名的文本。请注意,这具有理论意义
文件名大于整数的问题*/
snprintf(新名称,新大小,'%s%s',(int)在后缀,路径名之前,