Я прекрасно понимаю, что можно использовать класс string и просто написать cin>> str; а затем получить количество элементов. Я даже видел веселое решение при помощи malloc и realloc функций из C. но все же, интересно, есть ведь какой-то способ при помощи средств C++, а конкретно их потоков ввода и стандартных строк в виде массива символов прочитать из консоли строку, не имея понятия о ее размере, получить впоследствии ее размер и положить в динамически выделенный массив такого размера?? Вопрос не к спеху и не для какого-то задания, все чисто ради интереса, так что ваши ответы, типа "не парься и пользуйся тем, что дают" также приветствуются )
Ответ
cin >> str; запишет только до первого разделителя: http://ideone.com/Y5CJxD.
Если под строкой понимается последовательность, которая заканчивается переводом строки ('
'), то вам: std::getline() нужен: http://www.cplusplus.com/reference/string/string/getline/
А так, std::string это и так стандартное средство в C++. Если же хочется извратиться, то нужно читать блоками, проверять - есть ли перевод строки и агрегировать код, но лишнее нужно как-то хранить между вызовами. Либо, что проще, но медленнее - читать посимвольно, проверяя конец строки, например так:
istream& getline(istream& is, char *&buffer)
{
std::istream::sentry s(is);
if (s)
{
std::istreambuf_iterator
size_t size = 64;
size_t grow = 64;
size_t len = 0;
buffer = new char[size];
while (it != end && *it != '
')
{
if (len == (size - 1))
{
buffer = buffer_realloc(buffer, size, size + grow);
size += grow;
}
buffer[len++] = *it++;
}
buffer[len] = '\0';
}
return is;
}
Здесь я не привожу функцию buffer_realloc() - она простая. Использовать как-то так:
char *line = nullptr;
while (getline(std::cin, line))
{
if (line)
{
cout << line << endl;
delete[] line;
}
}
Либо вот вариант, где использует вектор:
istream& getline(istream& is, vector
const size_t grow = 64;
buffer.reserve(grow);
while (it != end && *it != '
')
{
if (buffer.size() == buffer.capacity() - 1)
{
buffer.reserve(buffer.size() + grow);
}
buffer.push_back(*it++);
}
buffer.push_back('\0');
}
return is;
}
Использовать как-то так:
vector
Тут реаллокация памяти ложится на плечи vector'а. От вас только почистить его (а можно и в гетлайн всунуть). Плюс бонусом сразу длинна строки за O(1): line.size() - 1
Вот законченные примеры:
http://ideone.com/Huj4eQ
http://ideone.com/CxNfg4
Но повторюсь: std::string стандартны для С++. Я слабо представляю условия, где есть потоки, но нет строк :)
Комментариев нет:
Отправить комментарий