Неправильно работает функция с С строкой
Задания- Функция принимает на вход C строчку. В результате она должна создать и вернуть новую строку, содержащую все символы, которые в этой строке встречаются только один раз.
Мой код
сhar* findOneCString(const char* str)
{
const size_t size = strlen(str);
char* strNew = new char[size + 1];
int num = 0;
for (size_t index = 0; index < size; ++index)
{
for (size_t j = size; j > index; --j)
{
if (str[index] == str[j])
{
}
else
{
strNew[num] = str[index];
++num;
}
}
}
strNew[num] = '\0';
return strNew;
}
У меня ошибки возникли и я не понимаю почему(
- утечка памяти
- записываются значения в новый массив пару раз.
Я понимаю что для большинства эта задачка легкая.. Но я не могу понять где я не так делаю
Ответы (2 шт):
Я маленько исправил ваш код, главным образом его внутренний цикл:
char* findOneCString(const char* str)
{
const size_t size = strlen(str);
char* strNew = new char[size + 1];
strNew[0] = '\n'; // сначала пустая строка
int num = 0;
for (size_t index = 0; index < size; ++index)
{
bool no_repeat = true; // очередной символ еще не повторился
for (size_t j = 0; j < strlen(strNew); ++j)
{
if (str[index] == strNew[j])
{
no_repeat = false; // когда он первый раз повторился,
break; // это хватит
}
}
if (no_repeat)
{
strNew[num] = str[index];
++num;
strNew[num] = '\0';
}
}
return strNew;
}
Tест:
cout << findOneCString("Abracadabra!");
выводит
Abracd!
Объяснение:
Не надо сравнивать символы заданной строки (параметра) с символами тот самой строки.
Лучше их сравнивать с символами новой строки strNew
, которую сначала сделаем пустой, и затем будем в нее постепенно добавлять символы из строки str
, которых в ней затем нет.
Если выделяем память через new [], то и освобождаем через delete[]. А вообще, возвращать указатель на где-то выделенную память - не самая хорошая идея. Гораздо лучше, когда тот, кто выделяет память, тот её и освобождает. А в функцию можно передать указатель на уже подготовленный буфер.
Выделять под результат strlen(str) + 1 символов нет необходимости. Больше 256 всё равно не получится.
#include <iostream>
void findOneCString(const char* str, char* res) {
int counter[256]{};
for (auto ptr = (unsigned char*)(str); *ptr != '\0'; ++ptr) {
++counter[*ptr];
}
int pos = 0;;
for (int ch = 0; ch < 256; ++ch) {
if (counter[ch] == 1) {
res[pos] = ch;
++pos;
}
}
res[pos] = '\0';
}
int main()
{
//if (!setlocale(LC_ALL, "")) return 1; // опционально
char buf[256];
findOneCString("ыфхщHello World!\nqwertyuiop", buf);
std::cout << buf;
std::cout << "\n";
system("pause");
}
Вывод:
!HWdipqtuwyфхщы
Если нужно сохранить порядок символов:
#include <iostream>
void findOneCString(const char* str, char* res) {
int counter[256]{};
for (auto ptr = (unsigned char*)(str); *ptr != '\0'; ++ptr) {
++counter[*ptr];
}
int pos = 0;;
for (auto ptr = (unsigned char*)(str); *ptr != '\0'; ++ptr) {
if (counter[*ptr] == 1) {
counter[*ptr] = 0;
res[pos] = *ptr;
++pos;
}
}
res[pos] = '\0';
}
int main()
{
//if (!setlocale(LC_ALL, "")) return 1; // опционально
char buf[256];
findOneCString("ыфхщHello World!\nqwertyuiop", buf);
std::cout << buf;
std::cout << "\n";
system("pause");
}
Вывод:
ыфхщH Wd!
qwtyuip