Нужна базовая помощь при разборе строки в C ++ - PullRequest
14 голосов
/ 02 февраля 2010

C ++ не мой любимый язык.

У меня есть файл, который содержит это:

e 225,370 35,75

Я хочу разделить e, 225, 370, 35 и 75 друг от друга на символы и целые, но у меня возникли проблемы. Я пытался делать все, что нашел в Интернете и в своей книге по С ++, но все равно ничего не получалось. Пожалуйста, помогите.

Мне было бы проще сделать это на Java.

Ответы [ 7 ]

13 голосов
/ 02 февраля 2010

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

int main()
{ 
   std::string data("e 225,370 35,75");
   char c1;
   int i1,i2,i3,i4;
   strtk::parse(data,", ",c1,i1,i2,i3,i4);
   return 0;
}

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

4 голосов
/ 02 февраля 2010

Если у вас есть контроль над форматом, будет (немного) легче читать, если вы удалите запятые, и просто введите, как

e 225 370 35 75

С этим форматом будет работать код Poita_ для чтения данных [править: он с тех пор обновляет свой код для явного чтения и пропуска запятых].В противном случае вам нужно явно пропустить запятые:

char ingore1, ignore2;
char ch;
int i[4];

file >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3];

[Редактировать: если вы параноик или действительно хотите подтвердить свой ввод, на данный момент вы можете проверить, что ignore1 и ignore2 содержит запятые.]

В большинстве случаев, однако, данные, вероятно, связаны, поэтому вы захотите прочитать всю строку в одну структуру (или класс):

struct data { 
    char ch;
    int i[4];

    std::istream &operator>>(std::istream &is, data &d) { 
        char ignore1, ignore2;
        return is >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3];
    }
};

Сделав это, вы можете одновременно прочитать весь data объект:

std::ifstream infile("my data file.txt");
data d;

infile >> d;

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

std::vector<data> d;

std::copy(std::istream_iterator<data>(infile), 
    std::istream_iterator<data>(),
    std::back_inserter(d));
3 голосов
/ 02 февраля 2010

Если вы хотите использовать старомодную среду выполнения C

FILE * pf = fopen(filename, "r");
char e;
int  a, b, c, d;
int ii = fscanf(pf, "%c %d,%d %d,%d", &e, &a, &b, &c, &d);
if (ii < 5) 
   printf("problem in the input file");
fclose (pf);

edit: добавлена ​​проверка ошибок на основе комментария от dreamlax

2 голосов
/ 02 февраля 2010

Используйте Boost Tokenizer, чтобы разбить строку. Я предполагаю, что только первый токен является символом, поэтому пример кода будет выглядеть примерно так:

#include <iostream>
#include <boost/tokenizer.hpp>
#include <string>
#include <vector>

using namespace std;

...

typedef boost::tokenizer<boost::char_separator<char> > tokenizer;

string teststring("e 225,370 35,75");
boost::char_separator<char> separators(", ");
tokenizer tokens(teststring, separators);
vector<string> substrings;
for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
{
    substrings.push_back(*iter);
}

и, вуаля, у вас есть все ваши подстроки в аккуратном векторе. Символ находится в подстроке [0] в виде std :: string, а следующие значения int находятся в подстроках [1] и последующих, также как std :: string Вам нужно будет преобразовать их в целочисленные значения. Для этого я предлагаю вам взглянуть на струнный поток.

2 голосов
/ 02 февраля 2010
#include <fstream>

/* ... */

ifstream file;
file.open("yourfile.txt");
char c, dummy;
int i[4];
file >> c >> i[0] >> dummy >> i[1] >> i[2] >> dummy >> i[3];
file.close();
2 голосов
/ 02 февраля 2010

Предполагая, что вы прочитали данные в строки ...

  1. strchr похож на String.index.
  2. strtol похож на Integer.parseInt ()

Что еще тебе нужно?

0 голосов
/ 02 февраля 2010
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
        ifstream f("a.txt"); // check for errors.

        char ch,dummy;
        int i1,i2,i3,i4;

        f>>ch>>i1>>dummy>>i2>>i3>>dummy>>i4;

        cout<<ch<<endl<<i1<<endl<<i2<<endl<<i3<<endl<<i4<<endl;

        return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...