Подтвердить что ты не робот

Форматированный ввод на С++: как "пропустить" токены?

Предположим, что у меня есть входной файл в этом формате:

VAL1 VAL2 VAL3
VAL1 VAL2 VAL3

Я пишу программу, которая будет интересовать только VAL1 и VAL3. В C, если бы я хотел "пропустить" второе значение, я бы сделал следующее:

char VAL1[LENGTH]; char VAL3[LENGTH];
FILE * input_file;
fscanf(input_file, "%s %*s %s", VAL1, VAL3);

Смысл, я бы использовал форматирование "% * s", чтобы fscanf() прочитал этот токен и пропустил его. Как это сделать с С++ cin? Есть ли подобная команда? Или мне нужно читать фиктивную переменную?

Спасибо заранее.

4b9b3361

Ответ 1

С++ String Toolkit Library (StrTk) имеет следующее решение вашей проблемы:

#include <string>
#include <deque>
#include "strtk.hpp"

int main()
{
   struct line_type
   {
      std::string val1;
      std::string val3;
   };

   std::deque<line_type> line_list;

   const std::string file_name = "data.txt";

   strtk::for_each_line(file_name,
                        [&line_list](const std::string& line)
                        {
                           strtk::ignore_token ignore;
                           line_type temp_line;
                           const bool result = strtk::parse(line,
                                                            " ",
                                                            temp_line.val1,
                                                            ignore,
                                                            temp_line.val3);
                           if (!result) return;
                           line_list.push_back(temp_line);
                        });

   return 0;
}

Дополнительные примеры можно найти здесь

Ответ 2

Доступна функция ignore:

std::cin << val1;
std::cin.ignore (9999, ' ');
std::cin << val3;

Первый аргумент определяет количество пропущенных символов, вторым параметром является разделитель, чтобы остановить пропуски.

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


Здесь пользовательский манипулятор:

template <class charT, class traits>
inline std::basic_istream<charT, traits> &
ignoreToken (std::basic_istream<charT, traits> &strm)
{
    strm.ignore (9999, ' ');
    return strm;
}

И вы можете использовать это следующим образом:

cin >> val1 >> ignoreToken >> val3 >> ignoreToken >> val5;

(ps - я не компилировал это, так что, возможно, опечатка).

Ответ 3

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

Есть целый ряд других проблем с getline(), но он должен работать для вашей проблемы.

Ответ 4

Я бы просто прочитал его в фиктивной переменной. Если вам это понадобится в конце концов, оно будет доступно.

Ответ 5

Вы можете использовать

cin.ignore(256, ' ');

Это будет игнорировать все до 256 символов или пробелов.

Изменить (форматирование и...): альтернативы, которые вы можете сделать:

int a, b;
cin >> a >> b >> b;