Есть несколько проблем с вашей программой:
- Объявление
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
, кажется, работает правильно.
Итак, собрав все это вместе:
#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);
}
}
Наконец, я согласен сКомментарий @ tadman.Поскольку входную строку в любом случае необходимо пройти для вычисления длины, мы также можем оптимизировать размер строки результата:
char* removeDup(const char *string)
{
size_t i, c = 0;
char *newString;
for (i = 0; string[i] != '\0'; i++)
c += (string[i] != string[i + 1]);
newString = malloc(c + 1);
for (i = c = 0; string[i] != '\0'; i++) {
if (string[i] != string[i + 1]) {
newString[c++] = string[i];
}
}
newString[c] = '\0';
return newString;
}