Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
12 / 12 / 3
Регистрация: 27.07.2012
Сообщений: 208

Конкатенация строк

27.08.2012, 22:41. Показов 2277. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Частью задания является реализовать функцию strcat. Возникает какая-то ошибка (см.фото).
1.Вы могли бы подсказать в чём ошибка?
2.Не по теме: как можно улучшить функцию read?

Вот код:

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
//read
char *Read(void){
    size_t size = 32;   //первоначальный размер строки
    size_t i = 0;       //индекс элемента строки
    int ch;             
    
    //выделим память для строки
    char *result = (char *)malloc(size);
    if(!result){
        cout << "Ошибка выделения памяти.\n";
        system("pause");
        exit(1);
    }
 
    //очистим стандартный поток ввода
    fflush(stdin);
    
    //считываем строку
    for(;;){
        ch = getchar(); 
        
        //если встретился пробел, то выходим из цикла
        if(isspace(ch)) break;
    
        //если длина строки превышает максимальный размер, то вернём нулевой указатель
        if(i == MAX_SIZE_STR - 1){
            cout << "Максимальная длина строки: " << MAX_SIZE_STR - 1 << '\n';
            return NULL;
        }
        //перевыделим память для, если это потребуется
        else if(i == size - 2){
            size *= 2;
            result = (char *)realloc(result,size);
            if(!result){
                cout << "Ошибка выделения памяти.\n";
                system("pause");
                exit(1);
            }
        }
        
        //запишем 1 символ из потока в строку
        result[i++] = ch;
    }
 
    //поставим завершающий нуль
    result[i] = '\0';
    
    if(ch!='\n') {
        cout << "Cтрока не должна содержать пробелов.\n";
        return NULL;
    }else if(Length(result) == 0) {
        cout << "Длина строку должна быть больше нуля.\n";
        return NULL;
    }
 
    return result;
}
//my strcat
char * Concat(const char *str,const char *str2){
    int i = 0;
    int n = Length(str);
    char *result;
 
    result = (char *)malloc(n + Length(str2) + 1);
    if(!result){
        cout << "Ошибка выделения памяти.\n";
        system("pause");
        exit(1);
    }
    
    while(result[i] = str[i]) i++;
    i = 0;
    while(result[n++] = str2[i++]);
    
    result[n] = 0;
    return result;
 
//main
void main(void){
    char ch;
    char *str, *str2, *result;
 
    setlocale(LC_ALL,"Rus");
 
    for(;;){
        system("cls");
 
        //выбор операции над строками
        ch = SelectOp();
        putchar('\n');
 
        if(ch == '0') break;
        
        do{
            cout << "Введите строку 1: ";
            str = Read();
        }while(!str);
        
        switch(ch){
case'2':
            do{
                cout << "Введите строку 2: ";
                str2 = Read();
            }while(!str2);
            
            putchar('\n');
 
            result = Concat(str,str2);
            
            cout << "строка 1: " << str << '\n';
            cout << "строка 2: " << str2 << '\n';
            cout << "сумма строк Concat: " << result << '\n';
            cout << "сумма строк strcat: " << strcat(str,str2) << '\n'; 
            
            free(str);
            free(str2);
            free(result);
            break;
            }
}
Миниатюры
Конкатенация строк  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.08.2012, 22:41
Ответы с готовыми решениями:

Конкатенация строк
Разбираю учебный пример - написать класс для работы со строками. Всего два поля: private: int _size; // длина строки, без...

конкатенация строк
Доброго времени суток! есть следующий код, который читает файл: char line; string str = &quot;&quot;; ifstream...

конкатенация строк
Подскажите, почему не компилируется код: std::string ExtractFileName(std::string filename) { if (filename.size() == 0)...

5
12 / 12 / 3
Регистрация: 27.07.2012
Сообщений: 208
27.08.2012, 23:03  [ТС]
Ошибка происходит при вводе строк максимальной длины.
Максимальная длина строки определена как глобальная константа:
[CPP]const int MAX_SIZE_STR = 101;
[CPP]

Добавлено через 4 минуты
Ошибка происходит почему-то при вызове free(result).

Добавлено через 13 минут
Если убрать в main free(result), то никаких ошибок не возникает. НО тогда происходит утечка. Почему free(result) вызывает ошибку?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.08.2012, 23:03
Цитата Сообщение от bgm313 Посмотреть сообщение
2.Не по теме: как можно улучшить функцию read?
не смешивать Си и С++(это касается кода в целом)

Цитата Сообщение от bgm313 Посмотреть сообщение
fflush(stdin);
это непереносимо и работает только под виндовс

Цитата Сообщение от bgm313 Посмотреть сообщение
exit(1);
exit в С++ не используют так как не будут вызваны деструкторы

Цитата Сообщение от bgm313 Посмотреть сообщение
(char *)malloc(size);
чем обосновано использование malloc ?
1
12 / 12 / 3
Регистрация: 27.07.2012
Сообщений: 208
27.08.2012, 23:17  [ТС]
malloc обосновано тем, что в программе требуется использовать функцию realloс. Да, конечно, можно было бы перегрузить оператор new, но в программе не используются классы.

Добавлено через 1 минуту
1.Что использовать вместо fflush(stdin)?
2.Почему всё таки выскакивает ошибка про кучу?

Добавлено через 1 минуту
Если надо могут скинуть весь код.
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
27.08.2012, 23:23
> Почему всё таки выскакивает ошибка про кучу?
Потому что вы гадите память, так как у вас где-то переполнение буфера. Скорее всего, из-за неправильно работающей Length() и ошибок на единицу. Помните, что нулевой байт в конце тоже учитывается при выделении памяти, но strlen() возвращает длину строки без него.

Далее, strcat или concat? strcat() дописывает вторую строку к первой, а не создаёт третью, где лежит конкатенация первых двух.

И наконец, возвращать указатель на объект, созданный в функции, — это в общем случае нехорошо. Потому что можно забыть вызвать free(). Кто память выделил, тот её и освобождает.
0
12 / 12 / 3
Регистрация: 27.07.2012
Сообщений: 208
27.08.2012, 23:36  [ТС]
0.Чем можно заменить fflush(stdin);

1.Требуется, чтобы функция concat записывала в 3 объект результат сложения.
Можно было бы поступить одним из след.способов:
a.Засунуть всё в глобальную переменную.
b.передать 3 параметр в функцию
с.сделать так, как сделал я
Какой из этих вариантов наиболее приемлемый? Может быть есть ещё какие-либо варианты?

2.По поводу ошибок в функциии Length. Я тоже так думал и выделил память для результирующей строки
размером 2*max_size + length(str) + length(str2); И всё равно выскакивает ошибка. Почему?

Вот скидываю полный код:

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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  #include <iostream>
using namespace std;
 
//максимальный размер строки
const int MAX_SIZE_STR = 101;
 
//сравнение строк 
int Compare(const char *str, const char *str2);
 
//длина строки
int Length(const char *str);
 
//копия строки str2
void Copy(char *str, const char *str2);
 
//конкатенация строк
char * Concat(const char *str,const char *str2);
 
//считает количество подстрок
int CalcSub(char *str, char *substr);
 
//считывает строку
char *  Read(void);
 
//выбор операции над строками
char SelectOp(void);
 
void main(void){
    char ch;
    char *str, *str2, *result;
 
    setlocale(LC_ALL,"Rus");
 
    for(;;){
        system("cls");
 
        //выбор операции над строками
        ch = SelectOp();
        putchar('\n');
 
        if(ch == '0') break;
        
        do{
            cout << "Введите строку 1: ";
            str = Read();
        }while(!str);
        
        switch(ch){
        case'1':
            do{
                cout << "Введите строку 2: ";
                str2 = Read();
            }while(!str);
            
            putchar('\n');
            
            cout << "Результат сравнения Compare: " << Compare(str,str2) << '\n'; 
            cout << "Результат сравнения strcmp: " << strcmp(str,str2) << '\n';   
            
            free(str);
            free(str2);
            break;
        case'2':
            do{
                cout << "Введите строку 2: ";
                str2 = Read();
            }while(!str2);
            
            putchar('\n');
 
            result = Concat(str,str2);
            
            cout << "строка 1: " << str << '\n';
            cout << "строка 2: " << str2 << '\n';
            cout << "сумма строк Concat: " << result << '\n';
            cout << "сумма строк strcat: " << strcat(str,str2) << '\n'; 
            
            free(result);
            free(str);
            free(str2);
            
            break;
        case'3':
            cout << "длина строки Length: " << Length(str) << '\n';
            cout << "длина строки strlen: " << strlen(str) << '\n';
            free(str);
            break;
        case'4':
            do{
                cout << "Введите подстроку: ";
                str2 = Read();
            }while(!str);
 
            putchar('\n');
 
            cout << "строка: " << str << '\n';
            cout << "подстрока: " << str2 << '\n';
            cout << "количество подстрок: " << CalcSub(str,str2) << '\n';
            
            free(str);
            free(str2);
            break;
        }
        
        putchar('\n');
        system("pause");
    }
}
 
char SelectOp(void){
    char ch;
    
    cout << "Меню:\n"
         << " 1.Сравнение строк.\n"
         << " 2.Конкатенация строк.\n"
         << " 3.Длина строки.\n"
         << " 4.Количество подстрок.\n";
    do{
        cout << "Сделайте выбор(0-выход): ";
        fflush(stdin);
    }while(scanf("%c",&ch)!=1 || cin.rdbuf()->in_avail()!=1 ||
        ch < '0' || ch > '4');
    return ch;
}
 
int Compare(const char *str, const char *str2){
    while(*str == *str2){
        if(!*str) return 0;
        str++; str2++;
    }
    if((*str - *str2) < 0) return -1;
    return 1;
}
 
int Length(const char *str){
    int len = 0;
    
    while(str[len]) len++;
    return len;
}
 
char * Concat(const char *str,const char *str2){
    int i = 0;
    int n = strlen(str);
    char *result = (char *)malloc(1000);
    
    if(!result){
        cout << "Ошибка выделения памяти.\n";
        system("pause");
        exit(1);
    }
    
    while(result[i] = str[i]) i++;
    i = 0;
    while(result[n++] = str2[i++]);
    
    result[n] = 0;
    return result;
}
 
int CalcSub(char *str, char *substr){
    int result = 0;
 
    while(strstr(str,substr)){
        result++;
        str+=Length(substr);
    }
    return result;
}
 
char *Read(void){
    size_t size = 32;   //первоначальный размер строки
    size_t i = 0;       //индекс элемента строки
    int ch;             
    
    //выделим память для строки
    char *result = (char *)malloc(size);
    if(!result){
        cout << "Ошибка выделения памяти.\n";
        system("pause");
        exit(1);
    }
 
    //очистим стандартный поток ввода
    fflush(stdin);
    
    //считываем строку
    for(;;){
        ch = getchar(); 
        
        //если встретился пробел, то выходим из цикла
        if(isspace(ch)) break;
    
        //если длина строки превышает максимальный размер, то вернём нулевой указатель
        if(i == MAX_SIZE_STR - 1){
            cout << "Максимальная длина строки: " << MAX_SIZE_STR - 1 << '\n';
            return NULL;
        }
        //перевыделим память для, если это потребуется
        else if(i == size - 2){
            size *= 2;
            result = (char *)realloc(result,size);
            if(!result){
                cout << "Ошибка выделения памяти.\n";
                system("pause");
                exit(1);
            }
        }
        
        //запишем 1 символ из потока в строку
        result[i++] = ch;
    }
 
    //поставим завершающий нуль
    result[i] = '\0';
    
    if(ch!='\n') {
        cout << "Cтрока не должна содержать пробелов.\n";
        return NULL;
    }else if(Length(result) == 0) {
        cout << "Длина строку должна быть больше нуля.\n";
        return NULL;
    }
 
    return result;
}
Добавлено через 5 минут
Хочу заметить в функции concat намеренно выделяется память размером 1000 б. - это в 5 раз больше чем может содержать результат сложения строк максимально допустимой длины.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.08.2012, 23:36
Помогаю со студенческими работами здесь

Конкатенация строк
struct Polya //struct for baza questions { WCHAR Question, var1, var2, var3, var4; WCHAR Answer; }; Polya *Quest = new...

Конкатенация строк
Имеется две строки string1 и string2, мне нужно что бы строка string3 содержала в себе обе, сначало string1, потом string2. Kак это сделать...

Конкатенация строк
Добрый день. Скажите, плз, как в ц++ соединить в единую строку следующее: myString = argv + i + &quot;тут некоторый текст.&quot; argv...

Конкатенация строк
Должно быть консольное приложение. Очень простой вопрос, но сам что-то завис, и немогу найти что хочу. Значит так есть такой кусок кода ...

Конкатенация строк
Написать программу, которая делает сложение унарных чисел. Я написал программу, она даже правильно считает, но как мне потом сказали,...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru