【问题标题】:Can't modify an array within a loop (C)不能在循环中修改数组 (C)
【发布时间】:2018-09-16 21:27:41
【问题描述】:

我目前正在开发一个小程序,需要一个函数返回一个字符串(字符数组),两个参数分别是(phrase,c)。 “短语”是一个字符串输入,“c”是将从短语中删除的字符。剩余的空格也将被删除。

#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 * rmchr(char * str, char *c) {
    //Declare result array
    char *strVal = (char *) malloc(sizeof(char) * strlen(str));

    //Iterate through each character
    for (int i = 0; i < strlen(str); i++) {
            *(strVal+i) = str[i];
        //Check if char matches 'c'
        if (strVal[i] != *c){
            //Assign filtered value to new array
            *(strVal+i) = str[i];
            printf("%c", strVal[i]);
        }
    }
    return strVal;
}

int main()
{
    char * result = rmchr("This is a great message to test with! It includes a lot of examples!","i");
    return 1;
}

在 'rmchr' 函数(if 语句)内部,数组准确地打印出我想要返回的方式:

Ths s a great message to test wth! It ncludes a lot of examples!

问题是我的返回变量“strVal”没有在 if 语句之外被修改。如何永久修改数组,以便我的理想输出将在“结果”内返回(在 main 内)。

【问题讨论】:

  • 循环中的第一行无条件复制字符
  • 您好,感谢您指出这一点!我删除了那行代码并将 if 语句替换为 if(str[i] != *c)。我测试了输出,似乎仍然没有修改 strVal 值。
  • 您必须维护两个索引来修改strVal 和从str 读取,因为在跳过字符后索引istrVal 中遥遥领先
  • 嗨。欢迎来到社区。如果没有某种有信誉的指南,学习 C 是非常不安全的,因为有些细微的细微差别没有明确定义,您似乎缺少基本概念。你在看哪本书?
  • “剩余的空格也会被删除”是什么意思?您的意思是对于每个被删除的字符,字符串中都不会出现字符,还是有一些启发式,例如“如果要删除的字符前面有一个或多个空格,后面有一个或多个空格,那么只有输出中应该出现一个空格”?为了你,我希望这只是第一个。

标签: c arrays string function


【解决方案1】:

我看到有几点需要解决。首先,此代码直接逐字复制输入字符串。相同的*(strVal+i) = str[i]; 分配发生在代码中的两个位置,忽略了与*c 的比较。如果没有一些二级索引变量j,就很难跟踪接收字符串的结尾。

补充说明:

  • 您的malloc 没有free;这会造成内存泄漏。

  • 您返回退出代码1,表示程序异常终止。 return 0 表示正常退出。

  • 不要将指针 malloc 返回;这可以隐藏错误。

  • 验证malloc成功,如果失败则退出。

  • strlen() 是一个线性时间操作,它在每次调用时遍历整个参数字符串。调用一次并将结果存储在变量中以节省周期。

  • 此代码不会根据需要处理多余空格的删除。

请参阅以下示例,了解解决上述某些问题的可能实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *rmchr(char *str, char *c) {
    int i = 0;
    int j = 0;
    int len = strlen(str);
    char *result = malloc(sizeof(*result) * (len + 1));

    if (result == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }

    while (i < len) {
        if (str[i] != *c) {
            result[j++] = str[i++];
        }
        else {
            for (i++; i < len && str[i] == ' '; i++);
        }
    }

    result[j] = '\0';
    return result;
}

int main() {
    char *result = rmchr("This is a great message to test with! It includes a lot of examples!", "i");

    for (int i = 0; i < strlen(result); i++) {
        printf("%c", result[i]);
    }

    free(result);
    return 0;
}

输出:

Ths s a great message to test wth! It ncludes a lot of examples! 

【讨论】:

  • 我非常感谢您的帮助,这使它更加清晰!这是一个绝妙的答案,只会让我再问一个问题。您会推荐哪些资源来提高我的 C 开发技能?
  • 没问题。试试K&R book
  • 请注意,此代码还会删除任何出现 *c 字符后的空格(例如 "a bc i e" -> a bc e),这可能不是 OP 的预期行为。
  • @Bob__ 好点;删除else 块来品尝。我可能误解了“剩余的空格也将被删除”。
猜你喜欢
  • 2019-06-20
  • 2021-08-03
  • 2019-08-07
  • 1970-01-01
相关资源
最近更新 更多