簡體   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