C++: istringstream зацикливается дважды

В настоящее время я работаю над фиктивным планировщиком процессов. Код читает текстовый файл поддельных процессов, и мне нужно иметь возможность анализировать файл. Текстовый файл форматируется, как показано ниже.

Pid     Bst     Arr     Pri     Dline   I/O
1       1       850     61      852     3
2       15      3980    82      3998    2
3       83      8095    51      8179    0
4       96      7262    66      7365    0
5       100     6529    1       6630    0
6       58      9068    24      9132    0
7       9       5148    35      5166    4
8       -8      5924    3       5925    0
9       100     -1      34      101     0
10      72      1918    43      -5      0

Чтобы сделать это, после поиска нескольких предложений о том, как лучше всего это сделать, я решил использовать istringstream. Код следующим образом.

int parseProcessFile(String filename){
    std::ifstream infile(filename);

    std::string line;
    while (std::getline(infile, line)){
        std::istringstream iss(line);
        int pid, bst, arr, pri, dline, io;
        if (!(infile >> pid >> bst >> arr >> pri >> dline >> io) || (pid < 0 || bst < 0 || arr < 0 || pri < 0 || dline < 0 || io < 0)) { 
            //do nothing, as this line won't read in appropriately
        } // error
        printf("%d | %d | %d | %d | %d \n", pid, bst, arr, pri, dline, io);
        // save process details
    }
    return 1;
}

long if просто проверяет правильность ввода (никаких нецелых чисел, не меньше 0)

По какой-то причине при запуске он дважды полностью зацикливается, распечатывая все, что является правильной строкой. Может ли кто-нибудь объяснить мне, почему это происходит?


person frederja    schedule 30.10.2013    source источник
comment
Если вы используете потоки для всего остального, зачем вдруг переключаться на printf для вывода?   -  person Zac Howland    schedule 30.10.2013
comment
!(infile >> это опечатка? Почему вы не читаете их из созданного вами стрима?   -  person bstamour    schedule 30.10.2013


Ответы (2)


if (!(infile >> pid >> bst >> arr >> pri >> dline >> io) ...)

Это будет читаться из файла (после того, как вы уже прочитали из файла). То, что вы хотели сделать, было

if (!(iss>> pid >> bst >> arr >> pri >> dline >> io) ...)

Который будет анализировать строку, которую вы только что прочитали, с помощью getline.

person Zac Howland    schedule 30.10.2013

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

int parseProcessFile(string filename){
    std::ifstream infile(filename.c_str());

    std::string line;
    while (std::getline(infile, line)){
        std::istringstream iss(line);
        int pid, bst, arr, pri, dline, io;
        if (!(iss >> pid >> bst >> arr >> pri >> dline >> io) || (pid < 0 || bst < 0 || arr < 0 || pri < 0 || dline < 0 || io < 0)) { 
            //do nothing, as this line won't read in appropriately
            continue;
        } // error
        printf("%d | %d | %d | %d | %d | %d \n", pid, bst, arr, pri, dline, io);
        // save process details
    }
    return 1;
}

Во-первых, если вы не собирались писать String (с большой буквы), вы используете std::string, и вам нужно будет передать const char * конструктору ifstream.

Во-вторых, вы хотели ввести iss вместо infile. Как сказал Зак, вы разбираете не то.

Наконец, если вы действительно не хотите ничего делать с недопустимой строкой, вы должны поместить printf в else или использовать continue, чтобы пропустить эту итерацию цикла при проверке на недействительность.

Надеюсь это поможет! :)

person Alex Reinking    schedule 30.10.2013