Нужна основная синтаксическая обработка строки в С++
С++ не является моим предпочтительным языком.
У меня есть файл, который содержит это:
e 225,370 35,75
Я хочу разделить e, 225, 370, 35 и 75 друг на друга на char и ints, но у меня проблемы. Я пробовал делать все, что я нашел в Интернете, и в моей книге на С++, но до сих пор не работает. Пожалуйста, помогите.
Мне было бы легче делать это на Java.
Ответы
Ответ 1
#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;
}
Ответ 2
С++ String Toolkit Library (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;
}
Дополнительные примеры можно найти Здесь
Ответ 3
Если у вас есть контроль над форматом, это будет (немного) легче читать, если вы устраните запятые и просто введите ввод, например
e 225 370 35 75
В этом формате код Poita_ для чтения данных будет работать [edit: он с момента обновления своего кода, чтобы явно прочитать и пропустить запятые]. В противном случае вам нужно явно пропустить запятую:
char ingore1, ignore2;
char ch;
int i[4];
file >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3];
[Edit: если вы параноик или вам действительно нужно проверить свой вход, на этом этапе вы можете проверить, что 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));
Ответ 4
Если вы хотите использовать старомодную C runtime
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
Ответ 5
Предполагая, что вы прочитали данные в строки...
- strchr подобен String.index.
- strtol похож на Integer.parseInt()
Что еще вам нужно?
Ответ 6
#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();
Ответ 7
Используйте Boost Tokenizer для разделения строки. Я предполагаю, что только первый токен - это char, поэтому пример кода будет примерно таким:
#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);
}
и, вуаля, у вас есть все ваши подстроки в аккуратном векторе. char находится в подстроках [0] как std::string, а следующие значения int находятся в подстроках [1] и последующих, также как std::string. Вам нужно будет преобразовать их в целые значения. Для этого я предлагаю вам посмотреть на stringstream.