Форум программистов, компьютерный форум CyberForum.ru

Функция редактирования строк - C++

Восстановить пароль Регистрация
 
cmath
Модератор
 Аватар для cmath
2415 / 1634 / 132
Регистрация: 11.08.2012
Сообщений: 3,252
Завершенные тесты: 5
30.08.2012, 16:43     Функция редактирования строк #1
Доброго времени суток. Столкнулся со следующей проблемой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void Erase(char **str, int pos, int n)
{
    char *newstr1, *newstr2;
    newstr2 = *str;
    int i = 0, len;
    len = strlen(newstr2);
    if (len >= pos + n)
    {
        newstr1 = new char[len - n];
        while(i != pos)
        {
            newstr1[i] = newstr2[i];
            i++;
        }
        while(i != len - n)
        {
            newstr1[i] = newstr2[i+n];
            i++;
            if(i == len - n)newstr1[i] = '\0';
        }
        delete []newstr2;
        *str = newstr1;     
    }
}
Эта функция удаляет из строки символы с pos+1 до pos+n включительно.
При одноразовом применении этой функции к строке все проходит нормально и без ошибок, но при повторном (я её вызывал для удаления всех вхождений заданной подстроки) применении появляется ошибка времени исполнения:
HEAP CORRUPTION DETECTED after Normal block (#123) at
0x0020EFB0.
CRT detected that the application wrote to memory after end of heap buffer.
Я уже раз 50 по этой функции проехался, использую точки останова. Ошибка возникает в *str = newstr1; когда я записываю в строку результат работы этой процедуры. пробовал убрать строку с delete (хотя это приводит к утечке памяти) не помогает. Помогите разобраться пожалуйста. Заранее благодарен.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.08.2012, 16:43     Функция редактирования строк
Посмотрите здесь:

C++ Функция конкатенации двух строк
Массивы строк и функция strcpy C++
Функция обработки строк C++
C++ Функция для обработки строк
не работает функция сравнения строк C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Andsteadur
152 / 136 / 3
Регистрация: 23.05.2009
Сообщений: 275
30.08.2012, 16:48     Функция редактирования строк #2
C++
1
void Erase(char **str, int pos, int n)
передаешь не указатель на строку, а массив указателей на строки?
cmath
Модератор
 Аватар для cmath
2415 / 1634 / 132
Регистрация: 11.08.2012
Сообщений: 3,252
Завершенные тесты: 5
30.08.2012, 17:04  [ТС]     Функция редактирования строк #3
Цитата Сообщение от Andsteadur Посмотреть сообщение
передаешь не указатель на строку, а массив указателей на строки?
Где вы увидели массив???? конструкция char **fdsfs - указатель на указатель, а не какой не массив (да, часто их используют, чтобы передать массивы в качестве параметров, но это не тот случай)

Добавлено через 1 минуту
Я передаю указатель на строку char *str в процедуру и это совершенно необходимая вещь, т.к. мне нужно, чтобы все изменения с str сохранились после выхода из процедуры
Catstail
Модератор
 Аватар для Catstail
21500 / 10253 / 1669
Регистрация: 12.02.2012
Сообщений: 17,139
30.08.2012, 17:07     Функция редактирования строк #4
Цитата Сообщение от Hydrogen Посмотреть сообщение
delete []newstr2;
- стр. 21 а где соотв. new?
cmath
Модератор
 Аватар для cmath
2415 / 1634 / 132
Регистрация: 11.08.2012
Сообщений: 3,252
Завершенные тесты: 5
30.08.2012, 17:11  [ТС]     Функция редактирования строк #5
Цитата Сообщение от Catstail Посмотреть сообщение
- стр. 21 а где соотв. new?
Память выделена в теле main() и функция не применяется, если str == NULL у меня это предусмотрено. Кроме того, вы не проанализировали код, как посмотрю (в newstr2 записан адрес на массив символов, переданных через указатель на str, его я и убиваю)
Catstail
Модератор
 Аватар для Catstail
21500 / 10253 / 1669
Регистрация: 12.02.2012
Сообщений: 17,139
30.08.2012, 17:13     Функция редактирования строк #6
Выложите полный код - я потестирую.
cmath
Модератор
 Аватар для cmath
2415 / 1634 / 132
Регистрация: 11.08.2012
Сообщений: 3,252
Завершенные тесты: 5
30.08.2012, 18:12  [ТС]     Функция редактирования строк #7
Цитата Сообщение от Catstail Посмотреть сообщение
Выложите полный код - я потестирую.
Пожалуйста
(только он претерпел некоторые изменения в теле main() я программу пишу для отработки придуманного алгоритма (чтобы применить его в другом проекте очень для меня важном (мое практическое задание))
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <windows.h>
#include <cstring>
#include <iostream>
 
using namespace std;
// прототип "стерки"
void Erase(char**, int, int);
// проверяет, является ли строка десятичным числом
bool isNumeral(char *str)
{
    int i = 0;
    bool poi = false;
 
    if(str[0]=='.')return false;
 
    while( str[i] != '\0')
    {
        if(str[i] == '.' && poi)return false;
        if(!(isdigit(str[i]) || str[i] == '.'))
        {
            return false;
        }
 
        if(str[i] == '.' && !poi)poi = true;
        i++;
    }
 
    return true;
}
 
 
// проверяет все ли '(' имеют пару ')' и, сообственно, наоборот
bool CheckPunct(char *str)
{
    int  counter1 = 0,
         counter2 = 0;
    int  i = 0;
    while(str[i] != '\0')
    {
        if(str[i] == '(')counter1++;
        if(str[i] == ')')counter2++;
        i++;
    }
    if(counter1 != counter2)return false;
    else return true;
}
 
// ищет операнды в строке, т.е. элементарные математические функции
int FindOperand(char *str, char *op)
{
    char* spec;
    spec = str;
    char* pos, *pCounter;
    int counter = 0;
    int count = 0;
    int len = strlen(op);
    pos = strstr(spec, op);
    while(pos != NULL)
    {
        pCounter = spec;
        while(pCounter != pos)
        {
            pCounter++;
            counter++;
        }
        Erase(&spec, counter, len);
        pos = strstr(spec, op);
        count++;
        counter -= counter;
    }
    return count;
}
// вставляет в строку 1 строку 2 после символа с номером pos
// ничего не делает, если pos больше числа символов в строке
void Insert(char **str1, char **str2, int pos)
{
    char *newstr1, *newstr2, *newstr3;
    int len1, len2;
    int i = 0,
        j = 0,
        k = 0;
    len1 = strlen(*str1);
    len2 = strlen(*str2);
    newstr2 = *str1;
    newstr3 = *str2;
    if(pos <= len1)
    {
        newstr1 = new char[len1 + len2];
        while(i != pos)
        {
            newstr1[i] = newstr2[i];
            i++;
            k++;
        }
        while(j != len2)
        {
            newstr1[i] = newstr3[j];
            i++;
            j++;
        }
        while(i != len1 + len2)
        {
            newstr1[i] = newstr2[k];
            i++;
            k++;
            if(i == len1 + len2)newstr1[i] = '\0';
        }
        delete []newstr2;
        *str1 = newstr1;
    }
}
 
// удаляет из строки n символов, идущих после символа с номером pos
// ничего не делает, если pos + n больше числа символов в строке 
void Erase(char **str, int pos, int n)
{
    char *newstr1, *newstr2;
    newstr2 = *str;
    int i = 0, len;
    len = strlen(newstr2);
    if (len >= pos + n)
    {
        newstr1 = new char[len - n];
        while(i != pos)
        {
            newstr1[i] = newstr2[i];
            i++;
        }
        while(i != len - n)
        {
            newstr1[i] = newstr2[i+n];
            i++;
            if(i == len - n)newstr1[i] = '\0';
        }
        delete []newstr2;
        *str = newstr1;     
    }
}
 
 
// копирует n символов из строки после символа с индексом pos
char* Copy(char *str, int pos, int n)
{
    char *newstr;
    if((int)strlen(str) >= pos + n)
    {
        int i = 0;
        newstr = new char[n];
        while(i < n)
        {
            newstr[i] = str[i + pos];
            i++;
            if(i == n)newstr[i] = '\0';
        }
        return newstr;
    }
    else return NULL;
}
 
int main()
{
    char *str;
    int pos, n;
    str = new char[50];
    cin >> str;
    cout << FindOperand(str, "sin(") << endl;
    system("pause");
    return 0;
};
Добавлено через 53 минуты
Ух... Избавился от ошибки другим способом: превратил процедуру в функцию, возвращающую значение, отпала необходимость в delete и выделении доп. памяти под всякие newstr.

Добавлено через 1 минуту
Ошибка была, похоже таки в delete. Хотя я не понял, чего это один раз она строку почистить-то могла?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.08.2012, 18:20     Функция редактирования строк
Еще ссылки по теме:

C++ Собственная функция strcat -сцепление строк
Функция для обработки строк C++
Функция редактирования файла C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Andsteadur
152 / 136 / 3
Регистрация: 23.05.2009
Сообщений: 275
30.08.2012, 18:20     Функция редактирования строк #8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <cstring>
#include <iostream>
 
using std::cin;
using std::cout;
using std::endl;
 
void Erase(char *& str, int pos, int n)
{
    int len = strlen(str);
    char *tmp = new char[len];
    memcpy(tmp, str, len);
    if (len >= pos + n)
    {
        delete [] str;
        str = new char[len - n + 1];
        memset(str, 0, len - n + 1);
        memcpy(str, tmp, pos);
        memcpy(str + pos, tmp + pos + n, len - pos - n);
    }
    delete [] tmp;
}
 
int main()
{
    char *str;
    const size_t szString = 50;
    str = new char[szString];
    cin.getline(str, szString,'\n');
    Erase(str, 3, 1);
    cout << str << endl;
    system("pause");
    return 0;
};
вот через ссылку на указатель
Yandex
Объявления
30.08.2012, 18:20     Функция редактирования строк
Ответ Создать тему
Опции темы

Текущее время: 01:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru