C 在找到特定字符时剪切字符串

C 在找到特定字符时剪切字符串,c,string,pointers,gcc,C,String,Pointers,Gcc,我正在做一个函数,当它找到某个字符时,它会“剪切”一个字符串,但我遇到了一些错误,我找不到失败的地方。守则: #包括 #包括 #包括 整数切割(字符*src,字符sep){ int i=0; 而(++i

我正在做一个函数,当它找到某个字符时,它会“剪切”一个字符串,但我遇到了一些错误,我找不到失败的地方。守则:

#包括
#包括
#包括
整数切割(字符*src,字符sep){
int i=0;
而(++i
如果我的逻辑没有失败,预期的输出应该是这样的:

#defineABC12
#defineABC
但我得到的却是:

#defineABC12
#defin

我不知道这是否改变了什么,但我在x86_64机器中使用了GCC

您的循环表达式有问题

while(++i < strlen(src) && *src && *src != sep)
      src++;
因此,您的循环会在预期之前退出

一般来说,你不需要这种“我”业务。“c”中的每个字符串都以空字符结尾,因此“*str”在您的情况下就足够了,以下内容应该可以完美地工作:

while(*src && *src != sep)
      src++;
例如,在其他情况下,当需要字符串长度时,应该在循环之前获得它

int len = strlen(src);
int i = 0;
while(i <= len && src[i] != sep)
   i++;
src[i-1] = 0;
int len=strlen(src);
int i=0;

而(i循环表达式存在问题

while(++i < strlen(src) && *src && *src != sep)
      src++;
因此,您的循环会在预期之前退出

一般来说,您不需要此“i”业务。“c”中的每个字符串都以空字符结尾,因此“*str”在您的情况下就足够了,以下操作应该可以很好地工作:

while(*src && *src != sep)
      src++;
例如,在其他情况下,当需要字符串长度时,应该在循环之前获得它

int len = strlen(src);
int i = 0;
while(i <= len && src[i] != sep)
   i++;
src[i-1] = 0;
int len=strlen(src);
int i=0;

虽然(i另一种简化方法是限制循环中递增的内容的数量。您正在递增
i
,但不需要同时递增指针
src
,只需使用索引符号,例如
src[i]
来向下处理字符串。这将允许您简化
cut()
功能用于:

int cut (char *src, char sep)
{
    int i = 0;
    
    for (; src[i] && src[i] != sep; i++) {}
    
    src[i] = '\0';
        
    return i;
}
示例使用/输出

在这种情况下,您的结果是:

$ ./bin/cutstr
#defineABC12
#defineABC
如果你能简化运动部件的数量,你就有助于保持逻辑的简洁

您也可以在不使用索引的情况下完成同样的任务,只需增加指针,例如

int cut (char *src, char sep)
{
    char *p = src;
    
    for (; *p && *p != sep; p++) {}
            
    *p = '\0';
        
    return p - src;
}
(相同的结果,两者都返回
10

或者,因为您包含了
string.h
,所以让
strchr()
来完成这项工作,例如

int cut (char *src, char sep)
{
    char *p = strchr (src, sep);
    
    if (p) {
        *p = 0;
        return p - src;
    }
    
    return strlen(src);
}
(结果相同)


如果您有任何问题,请告诉我。

另一种简化方法是限制循环中递增的内容的数量。您正在递增
i
,您不需要同时递增指针
src
,只需使用索引符号,例如
src[i]
向下处理字符串。这将允许您将
cut()
函数简化为:

int cut (char *src, char sep)
{
    int i = 0;
    
    for (; src[i] && src[i] != sep; i++) {}
    
    src[i] = '\0';
        
    return i;
}
示例使用/输出

在这种情况下,您的结果是:

$ ./bin/cutstr
#defineABC12
#defineABC
如果你能简化运动部件的数量,你就有助于保持逻辑的简洁

您也可以在不使用索引的情况下完成同样的任务,只需增加指针,例如

int cut (char *src, char sep)
{
    char *p = src;
    
    for (; *p && *p != sep; p++) {}
            
    *p = '\0';
        
    return p - src;
}
(相同的结果,两者都返回
10

或者,因为您包含了
string.h
,所以让
strchr()
来完成这项工作,例如

int cut (char *src, char sep)
{
    char *p = strchr (src, sep);
    
    if (p) {
        *p = 0;
        return p - src;
    }
    
    return strlen(src);
}
(结果相同)


如果您有任何问题,请告诉我。

strtok(第1行);
将完成这项工作。或者您可以使用
strchr
查找字符,如果返回值不为NULL,则将字符设置为
'\0'
,假设您无法使用标准库函数……您的cut函数在查找分隔符时递增src,但您在循环时通过
++i
strlen(src)
越来越短,而我越来越大。在开始修改src之前,您需要存储
strlen(src)
。就像这样:您真的不需要
++i
或者甚至是变量i,除非您确实需要返回修改后字符串的字符数(可以通过调用修改后的字符串上的strlen()获得):
while(++i
.Wow这是一行可怕的代码!缓慢是因为常量
strlen
调用。冗余是因为
*str
和混乱是因为开头的
++i
。实际返回剪切位置(修改字符串的长度)没有帮助,因为除非您提前知道未修改字符串的长度,否则这不会告诉您该字符串是否被修改。因此,如果您替换了某个内容,您可能希望返回一个指向该字符串其余部分的指针(在分隔符之后),如果不替换,则返回NULL(这与strtok()的功能非常相似)。或者,如果您返回一个有效字符串,则返回一个指针(非NULL)无论如何,如果替换,则可能返回一个指向字符串其余部分的指针;如果不替换,则返回字符串末尾的\0:
strtok(第“1”行);
将完成这项工作。或者您可以使用
strchr
查找字符,如果返回值不为NULL,则将字符设置为
'\0'
,假设您无法使用标准库函数……您的cut函数在查找分隔符时递增src,但您在循环时通过
++i
strlen(src)
越来越短,而我越来越大。在开始修改src之前,您需要存储
strlen(src)
。就像这样:您真的不需要
++i
或者甚至是变量i,除非您确实需要返回修改后字符串的字符数(可以通过调用修改后的字符串上的strlen()获得):
while(++i
。哇,这是一行可怕的代码!缓慢是因为不断的
strlen
调用。冗余是因为
*str
和混乱的becau