繁体   English   中英

strcpy() 不复制字符串中的第二个字符

[英]Strcpy() not copying the second character in a string

我在 C 中遇到了 strcpy() function 的问题。 在这个 function 中,我在缓冲区中取了一个字符串,该字符串包含类似于 '(213);' 的内容我正在尝试删除括号,因此 output 将类似于 200;。

for (i = 0; i < bufferlen; i++) {
        // check for '(' followed by a naked number followed by ')'
        // remove ')' by shifting the tail end of the expression
        // remove '(' by shifting the beginning of the expression
        if((buffer[i] == '(') && (isdigit(buffer[i+1]))){

            int numberLen = 0;
            int test =0;
            i++;
            while((isdigit(buffer[i]))){
                i++;
                numberLen++;
            }


            if(buffer[i] == ')'){
                int numberStart = i - numberLen-1;
                strcpy(&buffer[i], &buffer[i+1]);
                strcpy(&buffer[numberStart], &buffer[numberStart+1]);

                printf("buffer = %s\n", buffer);
            }
        }
    }

但是output如下

strcpy(&buffer[i], &buffer[i+1]); 之前的缓冲区 = (213);

strcpy(&buffer[i], &buffer[i+1]) 之后的缓冲区; = (213;

strcpy(&buffer[numberStart], &buffer[numberStart+1]) 之后的缓冲区; = 23;;

由于某种原因,第二个 strcpy function 删除了字符串的第二个值。 我也试过 strcpy(&buffer[0], &buffer[1]); 并且仍然得到相同的结果。 任何关于为什么会发生这种情况的见解将不胜感激。

继续评论, strcpy(&buffer[i], &buffer[i+1]); 其中sourcedest重叠导致Undefined Behavior ,使用memmove ,或者简单地使用几个指针。

C11 Standard - 7.24.2.3 strcpy function中禁止使用重叠的字符串(即相同的字符串)

如果我理解您的问题并且您只是想将"'(213)'"变成"213" ,那么您根本不需要任何string.h函数。 您可以简单地使用几个指针并沿着源字符串向下走,直到找到一个数字。 通过简单的分配开始将数字复制到dest 当遇到第一个非数字时, break你的复制循环。 保留一个标志以指示您何时“ in ”复制数字将允许您在第一个非数字处中断以将您的副本限制为找到的第一个数字序列(例如,从字符串"'(213)' (423)" ,只返回213而不是213423 )。 你可以做类似的事情:

char *extractdigits (char *dest, const char *src)
{
    /* you can check src != NULL here */
    char *p = dest;     /* pointer to dest (to preserve dest for return) */
    int in = 0;         /* simple flag to break loop when non-digit found */

    while (*src) {              /* loop over each char in src */
        if (isdigit(*src)) {    /* if it is a digit */
            *p++ = *src;        /* copy to dest */
            in = 1;             /* set in-number flag */
        }
        else if (in)            /* if in-number, break on non-digit */
            break;
        src++;                  /* increment src pointer */
    }
    *p = 0;             /* nul-terminate dest */

    return dest;        /* return pointer to dest (for convenience) */
}

一个简短的例子是:

#include <stdio.h>
#include <ctype.h>

#define MAXC 32

char *extractdigits (char *dest, const char *src)
{
    /* you can check src != NULL here */
    char *p = dest;     /* pointer to dest (to preserve dest for return) */
    int in = 0;         /* simple flag to break loop when non-digit found */

    while (*src) {              /* loop over each char in src */
        if (isdigit(*src)) {    /* if it is a digit */
            *p++ = *src;        /* copy to dest */
            in = 1;             /* set in-number flag */
        }
        else if (in)            /* if in-number, break on non-digit */
            break;
        src++;                  /* increment src pointer */
    }
    *p = 0;             /* nul-terminate dest */

    return dest;        /* return pointer to dest (for convenience) */
}

int main (void) {

    char digits[MAXC] = "";
    const char *string = "'(213}'";

    printf ("in : %s\nout: %s\n", string, extractdigits (digits, string));
}

示例使用/输出

$ ./bin/extractdigits
in : '(213}'
out: 213

如果您还有其他问题,请仔细查看并告诉我。

通过就地过滤“(”和“)”的方法。 时间复杂度为 O(N)。

int main(void) {
    char buffer[] = "(213)";
    int bufferLen = 5;

    int left = -1;
    for (int right = 0; right < bufferLen; ++right) {
        if ((buffer[right] != '(') && (buffer[right] != ')')) {
            ++left;
            buffer[left] = buffer[right];
        }
    }

    buffer[++left] = '\0';

    printf("%s", buffer);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM