从C

时间:2018-09-17 02:15:16

标签: c arrays char

我的代码存在循环问题。我有一个方法,需要两个字符数组(短语,字符)。字符数组包含必须单独读取并与短语进行比较的字符。如果匹配,则每次出现的字符都会从短语中删除。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//This method has two parameters: (str, c)
//It will remove all occurences of var 'c'
//inside of 'str'
char * rmstr(char * c, char * str) {

    //Declare counters and pointers
    int stemp = 0;
    int ctemp = 0; 
    char *p = str;
    char *d = c;
    //Retrieve str count
    while(str[stemp] != '\0') {
        stemp++;
    }
    //Retrieve c count
    while(c[ctemp] != '\0') {
        ctemp++;
    }
    //Output information
    printf("String Count: %d\n",stemp);
    printf("Character Count: %d\n",ctemp);
    //Iterate through arrays
    for (int i = 0; i != stemp; i++) {
        for (int j = 0; j != ctemp; j++) {
            if (c[j] != str[i]){
                *p++ = str[i];
            } 
                break;
        }
        printf("%s\n",str);
    }
    *p = 0;
    return str;
}

int main()
{
    char c[256] = "ema";
    char input[256] = "Great message!";
    char *result = rmstr(c, input);
    printf("%s", result);
    return 0;
}

在这种情况下,输入内容为“好消息!”我想删除所有出现的字符:e,m,a(如main中所指定)。

使用上面的代码,输出如下:

Grat mssag!

它仅循环1次迭代并删除'e'。我希望它也可以遍历“ m”和“ a”。

1 个答案:

答案 0 :(得分:1)

在修复导致内部循环退出的break;之后,重新排列循环并遍历要删除的字符,同时检查str中的字符可能是有意义的。如果您将str中的每个字符与字符c相匹配,则可以更方便地将其中的每个字符减1。如果您正在使用string.h之类的memmove中的函数来向下移动字符,则没关系。

仅使用指针手动完成str并删除c中所有字符的简单实现可能类似于以下内容:

#include <stdio.h>

char *rmstr (char *str, const char *chars)
{
    const char *c = chars;          /* set pointer to beginning of chars */
    while (*c) {                    /* loop over all chars with c */
        char *p = str;              /* set pointer to str */
        while (*p) {                /* loop over each char in str */
            if (*p == *c) {         /* if char in str should be removed */
                char *sp = p,       /* set start pointer at p */
                    *ep = p + 1;    /* set end pointer at p + 1 */
                do
                    *sp++ = *ep;    /* copy end to start to end of str */
                while (*ep++);      /* (nul-char copied on last iteration) */
            }
            p++;                    /* advance to next char in str */
        }
        c++;                        /* advance to next char in chars */
    }
    return str;     /* return modified str */
}

int main (void) {

    char c[] = "ema";
    char input[] = "Great message!";

    printf ("original: %s\n", input);
    printf ("modified: %s\n", rmstr (input, c));

    return 0;
}

(执行此操作的方法有很多-您在很大程度上取决于您。是否使用上面的指针,还是获取长度并使用字符串索引也是一个选择的问题)

使用/输出示例

$ ./bin/rmcharsinstr
original: Great message!
modified: Grt ssg!

如果您确实想使用memmove(以解决源和目标的重叠性质),则每次str中的字符将str中的其余字符向下移一匹配c中的字符,则可以按原始顺序保留循环,例如

#include <string.h>

char *rmstr (char *str, const char *chars)
{
    char *p = str;                  /* set pointer to str */
    while (*p) {                    /* loop over each char in str */
        const char *c = chars;      /* set pointer to beginning of chars */
        while (*c) {                /* loop over all chars with c */
            while (*c == *p) {      /* while the character matches */
                memmove (p, p + 1, strlen (p)); /* shuffle down by 1 */
                c = chars;          /* reset c = chars to check next */
            }
            c++;                    /* advance to next char in chars */
        }
        p++;                        /* advance to next char in str */
    }
    return str;     /* return modified str */
}

(确保您了解为什么在这种情况下必须重置c = chars;

最后,如果您确实想要这样做的简便方法,则可以使用strpbrkmemmove并将函数简化为:

#include <string.h>

char *rmstr (char *str, const char *chars)
{
    /* simply loop using strpbrk removing the character found */
    for (char *p = strpbrk (str, chars); p; p = strpbrk (str, chars))
        memmove (p, p+1, strlen(p));

    return str;     /* return modified str */
}

(在C语言中,猫皮总是有不止一种方法)

输出是相同的。看看这里的东西,如果您还有其他问题,请告诉我。