Печать указателей, возвращаемых функцией внутри цикла

#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 вызов функции для выполнения первой печати искажает данные в стеке, так что цикл печатает мусор.