Почему существуют две разные функции getline () (если они есть)? - PullRequest
22 голосов
/ 02 февраля 2011

Каждый раз, когда я делаю быстрый фрагмент строки кода 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 ]

23 голосов
/ 02 февраля 2011

Глобальная функция getline () работает с объектами C ++ std :: string .

Методы istream :: getline () работать с «классическими» строками C (указатели на char).

10 голосов
/ 02 февраля 2011

Имейте в виду, что стандартная библиотека состоит из 3 (основных) частей: IOStream, String и STL, а также несколько брошенных в лакомствах и C-заголовков.

Я не вижу ничего странного в том, что эти части слабо связаны (хотя хотелось бы, чтобы это было не так).

Другие несоответствия включают в себя: std::string::length против std::string::size, причем последний был добавлен для совместимости интерфейса с STL, а первый - для совместимости с более старым кодом.

7 голосов
/ 02 февраля 2011

Это общая проблема дизайна интерфейса. cin.getline() - это естественный способ сделать запрос, но чтобы избежать зависимости потокового кода от <string>, никакая функция cin.getline(std::string&) не может быть предложена. Отдельно стоящий getline(cin, s) может быть добавлен позже, когда строки введены в область видимости. Не проблема для char*, поскольку #include ничего не значит - все равно часть языка.

В некотором смысле, хорошо, когда языки позволяют более позднему коду добавлять дополнительные функции к существующим классам (например, Ruby), но в других случаях делокализация кусается и, в общем, ставит под угрозу сопровождение. Тогда, конечно, есть популярный аргумент в пользу минимальных функций-членов и большого количества автономных функций: лично я считаю, что не следует делать все возможное, чтобы сделать интерфейс менее интуитивным и выразительным, а каждый - своим.

1 голос
/ 02 февраля 2011

Да, современный способ C ++ - использовать функцию free и ввести std :: string.

Но IOStream имеет гораздо более длинную историю (стандартная версия, по крайней мере, третье воплощение того же дизайна), чем std :: string, и эта история объясняет, почему все так, как есть.

(Преимущество элемента getline заключается в том, что он не подразумевает динамическое распределение; эта характеристика может быть полезной в разы, но, вероятно, ее будет недостаточно, чтобы оправдать ее с нуля).

1 голос
/ 02 февраля 2011

Вариант getline внутри библиотеки iostreams не поддерживает строки как цели, поэтому библиотека строк определила вариант, который делает.

0 голосов
/ 13 июня 2018

Источник: https://www.reddit.com/r/learnprogramming/comments/4fx64h/is_there_a_difference_between_cingetline_and/

Функция-член cin.getline () работает со строками C (т.е. массивами char), тогда как свободная функция std :: getline () работает со строками C ++ (т.е. std :: string.) Вы не должны использовать строки C вообще при изучении C ++, что означает, что вы не должны использовать cin.getline ().

std :: getline () читает строку извходной поток до некоторого разделителя.По умолчанию в качестве разделителя используется '\ n', и нет смысла указывать этот третий аргумент, если вы просто собираетесь передать символ новой строки.Он не знает и не заботится о том, что содержится в этой строке, кроме проверки на разделитель.Если вы хотите попытаться проанализировать эту строку как целое число или значение с плавающей запятой, вы, безусловно, можете сделать это после чтения из потока, но это не работа std :: getline ().Он просто читает строку.

...