Есть ли лучший способ разобрать строку текста, как это? - PullRequest
4 голосов
/ 03 декабря 2011

У меня есть текстовый файл со строками текста, в которых есть строка, другая строка, за которой следуют до 4 целых чисел, например:

clear "clear water.png" 5 7
wet "wet water.png" 9 5 33 17
soft "soft rain falling.png" 

Единственный способ увидеть это:

читать до тех пор, пока не будет найдено место

установить строку для мокрой

читать до двойной кавычки

читать до второй двойной кавычки

установить вторую строку во влажную воду.png

пока не конец строки

читать до пробела

положить строку через поток строк

вставить полученное целое число в вектор типа int

Есть ли лучший способ сделать это?

Спасибо

Ответы [ 4 ]

5 голосов
/ 03 декабря 2011

Это та задача, для которой scanf и компания действительно сияют.

char first_string[33], second_string[129];

sscanf(input_string, 
    "%32s%*[^\"]%*c%128[^\"]%*c %d %d %d %d", 
    first_string, 
    second_string, 
    &first_int, 
    &second_int,
    &third_int,
    &fourth_int);

Возможно, вы захотите сделать это в операторе if, чтобы вы могли проверить возвращаемое значение, чтобы сообщитьВы, сколько из этих полей преобразовано (например, вы знаете, сколько целых чисел вы прочитали в конце).

Редактировать: возможно, было бы полезно какое-то объяснение.Давайте разберем, что:

% 32s читает строку до первого пробела (или 32 символа, в зависимости от того, что произойдет раньше).
% * [^ \ "] игнорирует ввод до первого ".
% * c игнорирует еще один байт ввода (сама цитата)
% 128 [^ \ "] читает строку в кавычке (т. Е. До следующего символа кавычки).
% *c Игнорирует закрывающую кавычку% d Читает целое число (которое мы делали четыре раза).

Пробел перед каждым %d действительно не нужен - он пропускает пробел, но без пробела, %d в любом случае пропустит первые пробелы.Я включил их просто, чтобы сделать его немного более читабельным.

1 голос
/ 03 декабря 2011

Безобразно, без проверки ошибок, но без каких-либо зависимостей от каких-либо нестандартных библиотек:

string s;
while(getline(fin, s))
{
    string word, quoted_string;
    vector<int> vec;

    istringstream line(s);
    line >> word;
    line.ignore(numeric_limits<streamsize>::max(), '"');
    getline(line, quoted_string, '"');
    int n;
    while(line >> n) vec.push_back(n);

    // do something with word, quoted_string and vec...
}
0 голосов
/ 03 декабря 2011

Да

Используйте getline для чтения по одной строке за раз.Разобрать строки с помощью библиотеки регулярных выражений .

0 голосов
/ 03 декабря 2011

В зависимости от ограничений входных строк вы можете попробовать разделить на double-quote, а затем разделить на space.

...