Задать вопрос
ogregor
@ogregor
арендатор vpn сервера debian

Как применить динамическую память для хранения соразмерного количества символов с ввода?

Задачка с курса по С++, но сам решить не смог, может кто поможет.

Реализуйте функцию getline, которая считывает поток ввода посимвольно, пока не достигнет конца потока или не встретит символ переноса строки ('\n'), и возвращает C-style строку с прочитанными символами.
Обратите внимание, что так как размер ввода заранее неизвестен, то вам нужно будет перевыделять память в процессе чтения, если в потоке ввода оказалось больше символов, чем вы ожидали.
Память, возвращенная из функции будет освобождена оператором delete[]. Символ переноса строки ('\n') добавлять в строку не нужно, но не забудьте, что в конце C-style строки должен быть завершающий нулевой символ.
Требования к реализации: при выполнении данного задания вы можете определять любые вспомогательные функции, если они вам нужны. Определять функцию main не нужно.

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

#include <iostream>

char *getline()
{
    char c = '\n';
    int p = 8;
    int i = 0;
    char *str = new char [p];
    
    while(std::cin.get(c) && c != '\n') {
        if (i > p) {
            p = p*2;
             std::cout << "i=" << i << "p=" << p << '\n';
            char *strNew = new char [p];
            for(int z=0; z<i;z++)                
                strNew[z] = str[z];           
            delete [] str;
            char *str = new char [p];
            for(int z=0; z<i;z++)                
                str[z] = strNew[z];           
            delete [] strNew;           
        }
            str[i] = c;
            std::cout << "ix=" << i << "p=" << p << "str = " << str[i] << '\n';
        i++;
    }
    str[i+1] = '\0';
    return str;
}

main() {
   std::cout << getline();
return 0;  
}
  • Вопрос задан
  • 1071 просмотр
Подписаться 1 Оценить 5 комментариев
Пригласить эксперта
Ответы на вопрос 3
@abcd0x00
Я так понял что инициализацию динамического массива надо делать внутри цикла и освобождать память здесь же.

Нужно сначала выделить буфер, а потом войти в цикл и писать в него посимвольно. Если он переполняется, то, не выходя из цикла, нужно его увеличить (выделить новый, скопировать данные, освободить старый, поставить новый на место старого).
Ответ написан
Adamos
@Adamos
А с чего бы его принимать?
У вас выделяется динамическая память размером в один байт.
Потом, начиная с этого адреса, впихивается весь ввод.
Уже на втором символе программа просто обязана упасть.
Причем даже при вводе длиной в один символ этим вторым будет завершающий ноль.

Даже в задании написано про перевыделение памяти - какого, собственно?
Ответ написан
profesor08
@profesor08
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

std::string to_string(std::vector<char> data)
{
    std::stringstream ss;
    
    for(size_t i = 0; i < data.size(); ++i)
    {
        if(i != 0)
        {
            ss << data[i];
        }
    }
    
    return ss.str();
}


int main()
{
  std::vector<char> str;
  char c;
  
  std::cout << "Enter text: ";
  
  while(std::cin.get(c) && c != '\n')
  {
    str.push_back(c);  
  }
  
  std::string result = to_string(str);
  
  std::cout << result;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы