Каков наилучший способ разделить пары значений ключа CSV на карту [duplicate]

Объект RegExp отслеживает lastIndex , где произошло совпадение, поэтому в последующих совпадениях он будет начинаться с последнего используемого индекса, а не 0. Посмотрите:

var query = 'Foo B';
var re = new RegExp(query, 'gi');
var result = [];
result.push(re.test('Foo Bar'));

alert(re.lastIndex);

result.push(re.test('Foo Bar'));

Если вы не хотите вручную сбросить lastIndex до 0 после каждого теста, просто удалите флаг g.

Вот алгоритм, который специфицирует спецификация (раздел 15.10.6.2): ​​

RegExp.prototype.exec (string)

Выполняет сопоставление регулярных выражений строки с регулярным выражением и возвращает объект Array, содержащий результаты совпадение или null, если строка не соответствует. Строка ToString (string) выполняется для поиска регулярного выражения следующим образом:

  1. Пусть S - значение ToString (string) .
  2. Пусть length - длина S.
  3. Пусть lastIndex - значение свойства lastIndex.
  4. Пусть i - значение ToInteger (lastIndex) .
  5. Если глобальное свойство ложно, пусть i = 0.
  6. Если I & lt; 0 или I> length, тогда установите lastIndex равным 0 и верните null.
  7. Вызов [[Match]], давая ему аргументы S и i. Если [[Match]] возвратил ошибку, перейдите к шагу 8; в противном случае r будет его результатом состояния и перейдите к шагу 10.
  8. Пусть i = i + 1.
  9. Перейдите к шагу 6. ​​
  10. Пусть e будет r endIndex.
  11. Если глобальное свойство истинно, установите lastIndex в e.
  12. Пусть n - длина массива захватов r. (Это то же значение, что и для NCapturingParens от 15.10.2.1.)
  13. Возвращает новый массив со следующими свойствами: Свойство index устанавливается в позицию согласованной подстроки в полной строке S. input свойство установлено равным S. Свойство length установлено в n + 1. Свойство 0 задано подстрочной подстрокой (т. е. частью S между смещением i включительно и смещением e exclusive). Для каждого целого i такого, что I> 0 и I ≤ n, задайте свойство с именем ToString (i) i-му элементу массива захватов r.
blockquote>

32
задан Michael Currie 11 September 2015 в 00:16
поделиться

12 ответов

cout << "Enter the number: ";
int number;
if (cin >> number)
{
    // throw away the rest of the line 
    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }
    cout << "Enter names: ";
    string name;
    // keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
    while (getline(cin, name))
        ...use name...
}
else
{
    std::cerr << "ERROR reading number\n";
    exit(EXIT_FAILURE);
}

В приведенном выше коде этот бит ...

    char c;
    while (cin.get(c) && c != '\n')
        if (!std::isspace(c))
        {
            std::cerr << "ERROR unexpected character '" << c << "' found\n";
            exit(EXIT_FAILURE);
        }

... проверяет остальную строку ввода после того, как номер содержит только пробелы.

Почему бы просто не использовать ignore?

Это довольно многословно, поэтому использование ignore в потоке после >> x является часто рекомендуемым альтернативным способом отбрасывания контента до следующей новой строки, но он рискует выбросить не-whitespace и при этом игнорируя поврежденные данные в файле. Вам может или не все равно, в зависимости от того, доверено ли содержимое файла, насколько важно избегать обработки поврежденных данных и т. Д.

Итак, когда вы будете использовать clear и ignore?

Таким образом, std::cin.clear()std::cin.igore()) для этого не требуется, но полезно для удаления состояния ошибки. Например, если вы хотите дать пользователю много шансов ввести действительный номер.

int x;
while (std::cout << "Enter a number: " &&
       !(std::cin >> x))
{
    if (std::cin.eof())
    {
        std::cerr << "ERROR unexpected EOF\n";
        exit(EXIT_FAILURE);
    }

    std::cin.clear();  // clear bad/fail/eof flags

    // have to ignore non-numeric character that caused cin >> x to
    // fail or there's no chance of it working next time; for "cin" it's
    // common to remove the entire suspect line and re-prompt the user for
    // input.
    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}

Не может быть проще с skipws или схожими?

Еще одна простая, но наполовину испеченная альтернатива ignore для вашего исходного требования использует std::skipws, чтобы пропустить любое количество пробелов перед чтением строк ...

if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...

... но если он вводится как «1E6» (например, какой-то ученый пытается ввести 1 000 000, но C ++ поддерживает эту нотацию для чисел с плавающей запятой ) не согласятся с этим, вы получите number, установленный на 1, и E6 считанные как первое значение name. Отдельно, если у вас есть действительное число, за которым следуют одна или несколько пустых строк, эти строки будут игнорироваться молча.

9
ответ дан Tony Delroy 21 August 2018 в 17:07
поделиться
  • 1
    Эмм, это не отвечает на вопрос или не устраняет проблему. -1 – Lightness Races in Orbit 11 September 2015 в 00:19
  • 2
    @LightnessRacesinOrbit: как это и не исправить проблему & quot ;? Первый вызов getline потребляет новую строку после числа и циклов до тех пор, пока не найдет непустую строку ... кажется, исправлено для меня. Вопрос ОП не спросил «почему?». проблема была, но сделал комментарий, что он не был уверен, почему clear может понадобиться - кто-то другой отредактировал 5-летний вопрос 2 дня назад, чтобы добавить это, существенно изменив суть. – Tony Delroy 13 September 2015 в 14:01
  • 3
    Теперь вы отредактировали [чужой] ответ, это лучше – Lightness Races in Orbit 13 September 2015 в 15:33
  • 4
    @LightnessRacesinOrbit: Я редактировал в своем комментарии к jonsca ответ, с 2011 года - ничего нового. – Tony Delroy 14 September 2015 в 00:24

Я только использовал

getline(cin >> ws,lard.i_npute);

со стандартным заголовком

#include <iostream>

в случаях, когда у меня возникали проблемы с возвратом каретки и работал с манипулятором ws. Я, вероятно, начну встраивать функции цикла в классы и использовать вызовы конструктора и деструктора atleast.

0
ответ дан 1911 Soldier 21 August 2018 в 17:07
поделиться
cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names

его довольно самообучающийся, в потоке, который используется cin >> number, есть\n, который присваивается именам при первом использовании. Повторное использование getline теперь записывает правильное значение.

1
ответ дан Aditya Gullapalli 21 August 2018 в 17:07
поделиться
cout << "Enter the number: ";
int number;
cin >> number;

cin.ignore(256, '\n'); // remaining input characters up to the next newline character
                       // are ignored

cout << "Enter names: ";
string names;
getline(cin, names);
16
ответ дан Cristiano Miranda 21 August 2018 в 17:07
поделиться

Другой способ сделать это - поставить

cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 

после того, как ваш cin>>number; полностью очистит входной буфер (отклонение всех дополнительных символов до тех пор, пока не будет найдена новая строка). Вы должны #include <limits> получить метод max().

15
ответ дан jonsca 21 August 2018 в 17:07
поделиться
  • 1
    +1 Мне просто интересно, что такое максимальный поток :-) – cnicutar 21 April 2011 в 06:55
  • 2
    @jonsca: & quot; отклонение всех дополнительных символов & quot; является сомнительным в большинстве производственных систем ... прекрасно есть белые пробелы, но отбрасывание неизвестных данных может легко и бесшумно привести к неправильным результатам. – Tony Delroy 21 April 2011 в 07:03
  • 3
    @cnicutar варьируется от реализации до реализации – jonsca 21 April 2011 в 07:08
  • 4
    @Tony Как насчет вместо getline, если у вас есть цикл, принимающий символы, расположенные после утверждения cin? Разумеется, дополнительные персонажи будут бросать в него ключ. Вы больше говорите о дырах в безопасности? – jonsca 21 April 2011 в 07:10
  • 5
    «петля принимает символы» ... если вы имеете в виду while (isspace(cin.peek())) cin.ignore() ... выглядит хорошо для меня. Re выше, я думал о том, что пользователь неправильно понимает требования к формату ввода или какой-то скрипт, генерирующий входные прерывания, но сломанный ввод, кажется, успешно обрабатывается, потому что он игнорируется - они могут в конечном итоге доверять сломанным результатам. Если вход не соответствует спецификации, лучше, чтобы ваша программа выработала ошибку. – Tony Delroy 21 April 2011 в 07:26

вы хотите использовать cin.ignore () после своих операторов cin, потому что вы хотите игнорировать «\n» слева в буфере после принятия переменной int cin.

У меня есть аналогичная программа я использовал с аналогичной проблемой:

#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main() {
    int i = 4;
    double d = 4.0;
    string s = "HackerRank ";

    // Declare second integer, double, and String variables.
    int n;
    double d2;
    string str;

    // Read and save an integer, double, and String to your variables.
    cin >> n;
    cin >> d2;

    cin.ignore();

    getline(cin, str);

    // Print the sum of both integer variables on a new line.
    cout << i + n << endl;


    // Print the sum of the double variables on a new line.
    cout << d + d2 << endl;

    // Concatenate and print the String variables on a new line
    cout << s << str << endl;

    // The 's' variable above should be printed first.

    return 0;
}
0
ответ дан lopezdp 21 August 2018 в 17:07
поделиться

Попробуйте:

int number;

cin >> number;

char firstCharacterOfNames;
cin >> firstCharacterOfNames;  // This will discard all leading white space.
                               // including new-line if there happen to be any.

cin.unget();                   // Put back the first character of the name.

std::string  names;
std::getline(cin, names);      // Read the names;

Альтернативно. Если вы знаете, что число и имена всегда будут на разных строках.

cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
std::getline(cin, names);
9
ответ дан Martin York 21 August 2018 в 17:07
поделиться
#include <iostream>
#include <string>

using namespace std;

int main()
{
    cout << "Enter the number: ";
    int number;
    cin >> number;
    cout << "Enter names: ";
    string names;

    // USE peek() TO SOLVE IT! ;)
    if (cin.peek() == '\n') {
        cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
    }

    getline(cin, names);

    return 0;
}

Просто загляните вперед, используя cin.peek(), и посмотрите, остается ли '\n' во внутреннем буфере cin. Если да: проигнорируйте его (в основном пропустите его)

-1
ответ дан max 21 August 2018 в 17:07
поделиться
  • 1
    Что, если это '\r'? Это замечательно хрупкое решение, которое я бы отклонил в обзоре кода. – Lightness Races in Orbit 11 September 2015 в 00:20

Концептуально, я думаю, вы хотите, чтобы каждый ответ был аккуратно одной строкой. Итак, почему бы вам не попробовать это?

cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);

cout << "Enter names: ";
string names;
getline(cin, names);

Код правильно использует первый символ новой строки, дает номер, если строка верна или выбрасывает исключение, если это не так. Все бесплатно!

0
ответ дан ngọcminh.oss 21 August 2018 в 17:07
поделиться

Или вы можете очистить входной буфер, чтобы прочитать строку

fflush (stdin)

, она определена в заголовке stdio.h .

Этот код работает ..

cout << "Enter the number: ";
int number;
cin >> number;

cout << "Enter names: ";
string names;
fflush(stdin);  //FLUSHING STDIN
getline(cin, names);
1
ответ дан Pzy64 21 August 2018 в 17:07
поделиться

Вы можете использовать std :: ws для извлечения любых пробельных символов во входном буфере перед использованием getline. Заголовок для std :: ws является sstream.

cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
5
ответ дан Rajeev Atmakuri 21 August 2018 в 17:07
поделиться

Вы можете найти ответ, который вы хотите найти в cppreference .

При использовании сразу после ввода с разделителями-пробелами, например. после int n; std::cin >> n;, getline потребляет символ конца, оставленный на входном потоке оператором >>, и немедленно возвращается. Общее решение состоит в том, чтобы игнорировать все оставшиеся символы в строке ввода с cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); перед переключением на линейно-ориентированный вход.

0
ответ дан shuaihanhungry 21 August 2018 в 17:07
поделиться
Другие вопросы по тегам:

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