使用C从字符串中删除连续重复的字符

时间:2018-05-10 18:23:42

标签: c arrays char

我试图从给定字符串中删除连续重复的字符。

示例:

  

bssdffFdcrrrtttii ***#

输出应该是:

  

bsdfFdcrti *#

这段代码不起作用,只打印第一个字符(b),我想了解我的错误。 当我进行printf测试时,它可以工作但不适用于空间。 我认为问题可能在于新的char数组。

void Ex6() {
    char* string[80];
    scanf("%s", &string);
    puts(removeDup(string));
}

char* removeDup(char *string) {
    int i, c = 0;
    char* newString[80];
    for (i = 0; i < strlen(string); i++) {
        if (string[i] != string[i + 1]) {
            newString[c++] = string[i];
        }
    }
    return newString;
}

2 个答案:

答案 0 :(得分:3)

您的计划有几个问题:

  • *.log的声明应该是newString,即一个字符数组,而不是一个指向字符的数组,同样适用于char newString[80]中的声明。
  • Ex6的调用应为scanf,因为scanf("%s", string)已经是字符数组的地址,但是......
  • 使用string从用户读取字符串,以确保您读取空格,如果重要,并且不超过缓冲区。
  • fgets在堆栈上分配,因此不应返回给调用者。最好做一个newString,或稍微不那么草率char *newString = strdup(string),它会调用char *newString = malloc(strlen(string)+1)一个足以保存原始字符串的内存块,因此没有重复的版本 - 评论正确地指出,这可以进行优化。原则上,调用者,即malloc,必须Ex6返回的指针,以避免内存泄漏,但在这么短的程序中几乎不重要。
  • 结果需要一个空终止符:free

否则,newString[c] = '\0'函数似乎可以正常工作。

所以,把所有这些放在一起:

removeDup

最后,我同意@ tadman的评论。由于无论如何必须遍历输入字符串来计算长度,我们也可以优化结果字符串的大小:

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

char* removeDup(const char *string)
{
    size_t i, c = 0;
    size_t string_len = strlen(string);
    char *newString = malloc(string_len + 1);

    for (i = 0; i < string_len; i++) {
        if (string[i] != string[i + 1]) {
            newString[c++] = string[i];
        }
    }
    newString[c] = '\0';

    return newString;
}

#define MAX_STRING_LEN 80

void Ex6() {
    char string[MAX_STRING_LEN];
    char* result;

    if (fgets(string, MAX_STRING_LEN, stdin) != NULL) {
        result = removeDup(string);

        printf("%s", result);
        free(result);
    }
}

答案 1 :(得分:2)

您的计划中存在相当多的问题。它甚至不会编译,更不用说运行了。此外,最棘手的问题是您从一个函数返回一个指向局部变量的指针,该函数在完成时停止其作用域。您的计划的简化版本如下:

void Ex6() 
{
   char string[80];
    scanf("%s", string);
        int i, c = 0;
    char newString[80];
    for (i = 0; i < strlen(string); i++) {
        if (string[i] != string[i + 1]) {
            newString[c++] = string[i];
        }
    }
    newString[c] = '\0';
    puts(newString);
}