Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 尝试从字符串中删除后缀但未成功_C_C Strings_Function Definition_Suffix - Fatal编程技术网

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”
第三个需要两次调用“return\u base\u filename(,)”,第一次使用“\”作为除数,第二次使用“.”

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”
第三个需要两次调用“return\u base\u filename(,)”,第一次使用“\”作为除数,第二次使用“.”

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