简体   繁体   English

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

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

I have been running into issues with the strcpy() function in C.我在 C 中遇到了 strcpy() function 的问题。 In this function I take a string in buffer and the string contains a something along the lines of '(213);'在这个 function 中,我在缓冲区中取了一个字符串,该字符串包含类似于 '(213);' 的内容and I am trying to remove the brackets so the output would be something like 200;.我正在尝试删除括号,因此 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);
            }
        }
    }

However, the output is as follows但是output如下

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

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

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

for some reason the second strcpy function removes the second value of the string.由于某种原因,第二个 strcpy function 删除了字符串的第二个值。 I have also tried strcpy(&buffer[0], &buffer[1]);我也试过 strcpy(&buffer[0], &buffer[1]); and still end up with the same results.并且仍然得到相同的结果。 Any insight as to why this is occurring would be greatly appreciated.任何关于为什么会发生这种情况的见解将不胜感激。

Continuing from the comment, strcpy(&buffer[i], &buffer[i+1]);继续评论, strcpy(&buffer[i], &buffer[i+1]); where source and dest overlap results in Undefined Behavior , use memmove , or simply use a couple of pointers instead.其中sourcedest重叠导致Undefined Behavior ,使用memmove ,或者简单地使用几个指针。

The prohibition on using strings that overlap (ie are the same string) is found in C11 Standard - 7.24.2.3 The strcpy function C11 Standard - 7.24.2.3 strcpy function中禁止使用重叠的字符串(即相同的字符串)

If I understand your question and you simply want to turn "'(213)'" into "213" , you don't need any of the string.h functions at all.如果我理解您的问题并且您只是想将"'(213)'"变成"213" ,那么您根本不需要任何string.h函数。 You can simply use a couple of pointers and walk down the source-string until you find a digit.您可以简单地使用几个指针并沿着源字符串向下走,直到找到一个数字。 Start copying digits to dest at that point by simple assignment.通过简单的分配开始将数字复制到dest When the first non-digit is encountered, break your copy loop.当遇到第一个非数字时, break你的复制循环。 Keeping a flag to indicate when you are " in " a number copying digits will allow you to break on the 1st non-digit to limit your copy to the first sequence of digits found (eg so from the string "'(213)' (423)" , only 213 is returned instead of 213423 ).保留一个标志以指示您何时“ in ”复制数字将允许您在第一个非数字处中断以将您的副本限制为找到的第一个数字序列(例如,从字符串"'(213)' (423)" ,只返回213而不是213423 )。 You could do somehting like:你可以做类似的事情:

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) */
}

A short example would be:一个简短的例子是:

#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));
}

Example Use/Output示例使用/输出

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

Look things over and let me know if you have further questions.如果您还有其他问题,请仔细查看并告诉我。

A method by filtering '(' and ')' in place.通过就地过滤“(”和“)”的方法。 Time complexity is O(N).时间复杂度为 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