C 尝试从字符串中删除后缀但未成功
我试图用下一种方法删除后缀,但最终输出与输入相同C 尝试从字符串中删除后缀但未成功,c,c-strings,function-definition,suffix,C,C Strings,Function Definition,Suffix,我试图用下一种方法删除后缀,但最终输出与输入相同 #包括 #包括 #包括 #定义后缀“.doc” 静态void removeSuffix(char**outNewFileName,const char*inFileName) { *outNewFileName=strdup(inFileName); outNewFileName[strlen(inFileName)-strlen(后缀)]; } int main() { char*fileName=“tmp.doc”; char*outnew
#包括
#包括
#包括
#定义后缀“.doc”
静态void removeSuffix(char**outNewFileName,const char*inFileName)
{
*outNewFileName=strdup(inFileName);
outNewFileName[strlen(inFileName)-strlen(后缀)];
}
int main()
{
char*fileName=“tmp.doc”;
char*outnewFileName=NULL;
removeSuffix(&outnewFileName,fileName);
免费(outnewFileName);
返回0;
}
例如,如果文件名是tmp.doc outnewFileName也是tmp.doc“…从字符串中删除后缀,但没有成功”
在以下方面:
outNewFileName[strlen(inFileName) - strlen(SUFFIX)];
正在修改的变量需要表示为(*outNewFileName)
,因此将上述内容更改为:
(*outNewFileName)[strlen(inFileName) - strlen(SUFFIX)];
此外,在这种方法中,进行数学运算以获得数组索引是可能的,但可能很难正确执行,并且不是从字符串中剪掉文件扩展名的唯一方法。以下是一种替代方法,例如,它不需要使用#define
值,也不需要进行数组索引计算。(但需要
文件扩展名分隔符)
编辑以处理评论:
另一种比前一种方法更灵活的方法是,创建一种功能,指定要标识文件扩展名的分隔符,并将其作为参数传递,以返回字符串中直到最后一次出现该分隔符的部分。例如:
strcpy((*outNewFileName), return_base_filename((*outNewFileName), '.'));
其中return\u base\u filename()
定义为:
//returns string upto last occurance of delimiter.
char * return_base_filename(char *in, char delimiter)
{
char *ptr = in;
char *ptrKeep = NULL;
while(*ptr)
{
if(*ptr == delimiter)
{
ptrKeep = ptr;
}
ptr++;
}
in[ptrKeep - in]=0;
return in;
}
请注意,此方法适用于以下文件名/目录形式:
“base.ext”
“base1.base2.base3.ext”
“C:\\one\\two\\three\\with.this.file.txt”
char buf[] = {"C:\\one\\two\\three\\with.this.file.txt"};
strcpy(buf, return_base_filename(buf,'\\'));
strcpy(buf, return_base_filename(buf,'.'));
“…从字符串中删除后缀,但未成功”
在以下方面:
outNewFileName[strlen(inFileName) - strlen(SUFFIX)];
正在修改的变量需要表示为(*outNewFileName)
,因此将上述内容更改为:
(*outNewFileName)[strlen(inFileName) - strlen(SUFFIX)];
此外,在这种方法中,进行数学运算以获得数组索引是可能的,但可能很难正确执行,并且不是从字符串中剪掉文件扩展名的唯一方法。以下是一种替代方法,例如,它不需要使用#define
值,也不需要进行数组索引计算。(但需要
文件扩展名分隔符)
编辑以处理评论:
另一种比前一种方法更灵活的方法是,创建一种功能,指定要标识文件扩展名的分隔符,并将其作为参数传递,以返回字符串中直到最后一次出现该分隔符的部分。例如:
strcpy((*outNewFileName), return_base_filename((*outNewFileName), '.'));
其中return\u base\u filename()
定义为:
//returns string upto last occurance of delimiter.
char * return_base_filename(char *in, char delimiter)
{
char *ptr = in;
char *ptrKeep = NULL;
while(*ptr)
{
if(*ptr == delimiter)
{
ptrKeep = ptr;
}
ptr++;
}
in[ptrKeep - in]=0;
return in;
}
请注意,此方法适用于以下文件名/目录形式:
“base.ext”
“base1.base2.base3.ext”
“C:\\one\\two\\three\\with.this.file.txt”
char buf[] = {"C:\\one\\two\\three\\with.this.file.txt"};
strcpy(buf, return_base_filename(buf,'\\'));
strcpy(buf, return_base_filename(buf,'.'));
你很接近!您的
strlen(inFileName)-strlen(后缀)
表达式找到了终止新字符串的正确位置,但实际上您并没有对该表达式执行任何操作
要在该位置终止字符串,请将char
的值设置为zero(即nul
终止符):
static void removeSuffix(char**outNewFileName,const char*inFileName)
{
*outNewFileName=strdup(inFileName);
(*outNewFileName)[strlen(inFileName)-strlen(后缀)]='\0';
}
在这段代码中,我们使用(*outNewFileName)
来表示新的字符串数组,使用方括号中的偏移量来表示需要更改为nul
的实际字符。(圆括号是必需的,因为[]
运算符的优先级高于*
运算符。)
注意:如注释中所指出的,如果启用了完整的编译器警告,您将看到以下内容(从clang cl): 警告:表达式结果未使用[-Wunused值]
请随时询问任何进一步的澄清和/或解释。您非常接近!您的
strlen(inFileName)-strlen(后缀)
表达式找到了终止新字符串的正确位置,但实际上您并没有对该表达式执行任何操作
要在该位置终止字符串,请将char
的值设置为zero(即nul
终止符):
static void removeSuffix(char**outNewFileName,const char*inFileName)
{
*outNewFileName=strdup(inFileName);
(*outNewFileName)[strlen(inFileName)-strlen(后缀)]='\0';
}
在这段代码中,我们使用(*outNewFileName)
来表示新的字符串数组,使用方括号中的偏移量来表示需要更改为nul
的实际字符。(圆括号是必需的,因为[]
运算符的优先级高于*
运算符。)
注意:如注释中所指出的,如果启用了完整的编译器警告,您将看到以下内容(从clang cl): 警告:表达式结果未使用[-Wunused值] 请随时要求进一步澄清和/或解释。我宁愿:
char* strrrstr(const char *haystack, const char *needle)
{
const char *r = NULL;
size_t nlen = strlen(needle);
if(haystack && needle)
{
while (1)
{
char *p = strstr(haystack, needle);
if (!p)
break;
r = p;
haystack = p + nlen;
}
}
return (char *)r;
}
#define SUFFIX ".doc"
static char *removeSuffix(const char *str, const char *suffix)
{
char *newString = strdup(str);
char *pos;
if(newString)
{
pos = strrrstr(newString, suffix);
if(pos) *pos = 0;
}
return newString;
}
int main ()
{
static char *fileName = "tmp.doctmp.doc";
char *outnewFileName;
outnewFileName = removeSuffix(fileName, SUFFIX);
printf("%s\n", outnewFileName);
free(outnewFileName);
return 0;
}
您应该始终阅读警告,并将警告级别设置为可能的最大值。如果你这样做了:
<source>:36:23: warning: statement with no effect [-Wunused-value]
36 | outNewFileName[strlen(inFileName) - strlen(SUFFIX)];
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:36:23:警告:声明无效[-Wunused-
tmp.doc