Форматированный ввод C ++: как «пропустить» токены? - PullRequest
20 голосов
/ 12 июня 2009

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

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 C ++? Есть ли подобная команда? Или я должен читать фиктивную переменную?

Заранее спасибо.

Ответы [ 5 ]

14 голосов
/ 30 декабря 2010

Библиотека C ++ String Toolkit (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;
}

Больше примеров можно найти Здесь

7 голосов
/ 12 июня 2009

Доступна функция 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 - я не скомпилировал это, так что может быть опечатка).

2 голосов
/ 12 июня 2009

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

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

1 голос
/ 12 июня 2009

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

0 голосов
/ 12 июня 2009

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

cin.ignore(256, ' ');

При этом будут игнорироваться все, вплоть до 256 символов или пробела.

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

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