#c #pointers
#c #указатели
Вопрос:
Я создаю программу на c , которая заменит все пробелы из массива символов на » «. Например, «Это некоторый текст с некоторыми пробелами» будет преобразован в «This is some text with some spaces»
ПОЖАЛУЙСТА, ПОСМОТРИТЕ В КОММЕНТАРИЯХ К ПРОГРАММЕ, КАКАЯ СТРОКА НЕ РАБОТАЕТ ДОЛЖНЫМ ОБРАЗОМ.
функция replacer в этой программе принимает указатель на массив символов и размер строки. Затем метод создает новый массив символов с замененными пробелами, а функция возвращает указатель на замененный массив символов.
Проблема в этой программе заключается в печати массива символов в функции main, указатель на который возвращается заменителем.
«replaced» — это переменная указателя, которая указывает на замененную строку. В основной функции я пытаюсь распечатать массив символов, используя «замененный» указатель.
Если я печатаю все вручную, все работает нормально. Например, если я сделаю : cout << *replaced << *(replaced 1) << *(replaced 2)
…. Будет напечатана вся строка.
Но внутри цикла это дает мне значение мусора. Пожалуйста, дайте мне знать, где в коде я допускаю какую-либо ошибку. Спасибо.
#include <iostream>
using namespace std;
char * replacer(char * text, unsigned int size )
{
int space_count = 0, i = 0, new_size = 0;
cout << "Given text : ";
for(i = 0;i < size;i )
{
cout << *(text i) ;
char temp = *(text i);
if (temp == ' ')
{
space_count ;
}
}
cout << endl;
cout << "Number of spaces in given text : " << space_count << endl;
new_size = size ( 2 * space_count );
char replaced_string[new_size];
int counter = 0 ;
for(i = 0 ;i < size; i )
{
char temp = *(text i);
if(temp == ' ')
{
replaced_string[counter ] = '%';
replaced_string[counter ] = '2';
replaced_string[counter ] = '0';
}
else
{
replaced_string[counter ] = temp;
}
}
cout << "in replacer method : " << replaced_string << endl;
char * pointer_to_replaced;
pointer_to_replaced = replaced_string;
return pointer_to_replaced;
}
int main()
{
int t;
char original[] = "This is some text with some spaces";
char * original_pointer = original;
char *replaced;
replaced = replacer(original_pointer, sizeof(original));
//cout << *(replaced) << *(replaced 1) << *(replaced 2) << *(replaced 3) << *(replaced 4) << endl;
// ABOVE LINE WORKS FINE
for(t=0;t<20;t )
{
cout<<*(replaced t); // THIS IS NOT WORKING PROPERLY
}
cout <<endl;
return 0;
}
Комментарии:
1. Это почти уже сделано для вас с
std::string::replace
помощью .2. Поскольку вы вызываете эту программу на C , я рекомендую избавиться от компонентов C, таких как массивы символов. Используйте
std::string
. Вот откуда берутся ваши ошибки.3.
replaced_string
не завершается нулевым значением.
Ответ №1:
Первая проблема заключается в том, что вы выделяете replaced_string
в стеке, а затем ожидаете, что он сохранит свое значение после возврата из функции. Вместо этого вы должны выделить в куче, а затем запомнить в delete[]
памяти. Стек исчезает, когда функция возвращается.
// char replaced_string[new_size];
char* replaced_string = new char[new_size];
Вторая проблема заключается в том, что вам нужно обнулить свой replaced_string
после цикла.
replaced_string[counter] = '';
Кроме того, вам не нужно выполнять цикл, чтобы распечатать возвращаемое значение. Вы можете использовать cout
напрямую.
cout << replaced << endl;
Могут быть и другие скрытые проблемы, но исправление этих трех сделает код функциональным.
Комментарии:
1. Спасибо. Но тогда как работает ручная печать всех символов? cout << *заменено << *(заменено 1) << *(заменено 2) …
2. Да, хранение в куче решает проблему. Но все же было бы здорово, если бы вы дали конкретное объяснение, почему работает ручная печать указателей
3. @Hardik, когда вы пытаетесь получить доступ к переменным стека из фрейма стека, срок действия которого уже истек, у вас неопределенное поведение. Что касается вашего конкретного вопроса, это, вероятно, связано с тем, что
cout
вызов функции для выполнения первой печати искажает данные в стеке, так что цикл печатает мусор.