Почему существуют две разные функции getline () (если они действительно существуют)?
каждый раз, когда я делаю быстрый фрагмент строки кода C++
std::string s;
cin >> s;
Я проклинаю себя, потому что забыл, что он останавливается на пробелах, а не получает целую строку.
тогда, вспоминая getline
, я неизменно путаюсь в отношении двух разновидностей:
std::string s;
getline (std::cin, s);
и:
char cs[256];
std::cin.getline (cs, sizeof (cs));
есть ли на самом деле разница между этими двумя, кроме типа данных?
мне кажется, что путь C++ должен быть первым. Под чем обстоятельства я бы использовал последнее, учитывая, что я, вероятно, должен использовать реальные строки в любом случае, символьных массивов с нулевым завершением?
и, поскольку ввод действительно должен быть областью действия входных потоков, почему бы не бывшая часть istream
?
6 ответов
имейте в виду, что стандартная библиотека состоит из 3 (основных) частей: IOStream, String и STL, плюс некоторые брошенные лакомства и C-заголовки.
Я не вижу ничего странного в том, что эти части слабо связаны (хотя я бы хотел, чтобы это было не так).
другие несоответствия включают:std::string::length
vs std::string::size
, последний был добавлен для совместимости интерфейса с STL, а первый был сохранен для совместимости со старым кодом.
глобальные вызовом getLine() функция работает с C++ std:: string объекты.
на istream:: getline() методы работают с" классическими " строками C (указатели на char
).
это общая проблема дизайна интерфейса. cin.getline()
- Это естественный способ сделать запрос, но избежать зависимости кода потока от <string>
, нет cin.getline(std::string&)
функцию можно предложить. Свободныйgetline(cin, s)
может быть добавлен позже, как только строки были введены в область. Не проблема для char*
как там ничего #include
- все равно часть языка.
в некотором смысле приятно, когда языки позволяют более позднему коду добавлять дополнительные функции к существующим классам (например, Ruby), но другими способами делокализация кусает и, ну, компрометирует ремонтопригодность. Тогда, конечно, есть популярный аргумент для минимальных функций-членов и множества самостоятельных функций: я лично думаю, что это не должно быть принято так далеко, чтобы сделать интерфейс менее интуитивным и выразительным, но каждый по-своему.
на getline
variant внутри библиотеки iostreams не поддерживает строки в качестве целей, поэтому библиотека строк определила вариант, который это делает.
Да современный способ C++ - использовать свободную функцию и ввести строку std::.
но IOStream имеет гораздо более длинную историю (стандартная версия, по крайней мере, третья инкарнация того же дизайна), чем std::string, и эта история объясняет, почему все так, как есть.
(член getline имеет то преимущество, что он не подразумевает динамического распределения; эта характеристика может быть удобна во время, но, вероятно, недостаточно, чтобы оправдать ее с нуля дизайн.)
функция-член cin.getline () работает со строками C (т. е. массивами char), тогда как свободная функция std::getline () работает со строками C++ (т. е. std::string.) Вы не должны использовать строки C вообще при изучении C++, что означает, что вы не должны использовать cin.Гэтлину().
std:: getline () считывает строку из входного потока вверх некоторым ограничителем. Разделитель по умолчанию - "\n", и нет причин указывать этот третий аргумент, если вы просто собираетесь передать символ новой строки. Он не знает или не заботится о том, что содержится в этой строке, кроме проверки разделителя. Если вы хотите попытаться проанализировать эту строку как целое число или значение с плавающей запятой, вы можете сделать это после чтения из потока, но это не задание std::getline (). Он просто читает строку.