Невозможно понять это возвращаемое значение программы C ++ - PullRequest
0 голосов
/ 15 мая 2018

Я наткнулся на следующую программу в TCPPPL по Страуструпу:

int main()
{
    string from, to;
    cin >> from >> to;  // get source and target file names

    ifstream is {from};  // input stream for file "from"
    istream_iterator<string> ii {is};  // input iterator for stream
    istream_iterator<string> eos {};  // input sentinel

    ofstream os{to};    // output stream for file "to"
    ostream_iterator<string> oo {os,"\n"};   // output iterator for stream

    vector<string> b {ii,eos};  // b is a vector initialized from input [ii:eos)
    sort(b.begin(),b.end());   // sor t the buffer

    unique_copy(b.begin(),b.end(),oo);// copy buffer to output, discard //replicated values
    return !is.eof() || !os; // return error state (§2.2.1, §38.3)
}

Мои вопросы - какая последняя строка, т. Е. return !is.eof() ||!os; делает. Я знаю, что если main возвращает ненулевое значение, то это означает ошибку, но что здесь возвращается?

Ответы [ 6 ]

0 голосов
/ 15 мая 2018

Эта программа выводит упорядоченный список слов, найденных во входном файле в файле, возвращает 0 в случае успеха или 1 в случае ошибки.

Цель этой программы - показать, как мощные хорошие итераторы могут быть использованы для краткой реализации общей проблемы.

  • istream_iterator< std::string > позволяет читать файл (он же поток ввода файла) в словах, то есть с использованием пробелов в качестве разделителя. vector< string > b {ii,eos}; инициализировать вектор, перебирая файловый итератор. Таким образом содержимое файлов загружается в память.

  • ostream_iterator< string> oo {os,"\n"}; позволяет записывать в выходной поток (здесь поток файлов), используя возврат строки в качестве разделителя

  • is.eof() будет ложным, если файл не в конце, что означает, что файл не был прочитан

  • ! Os - отрицательный оператор выходного потока , который возвращает true, если произошла ошибка. Могут возникнуть ошибки, но это будет означать, что выходной файл не будет создан.
0 голосов
/ 15 мая 2018

is.eof() возвращает true, если для is.
достигнут конец файла. * Это просто.

os - это объект std::ostream, который имеет operator bool().Это означает, что os неявно преобразуется в bool.После этого возвращается true, если в потоке нет ошибок.

Оператор !is.eof() || !os является статусом программы.
Его можно перевести на:

either the eof is not occurred for `is` OR `os` has some errors

Это может быть далее переведено (используя законы Де Моргана) в:

eof is occured for `is` AND `os` has no errors

Это означает, что программа успешна, если входной поток прочитан полностью, а вывод был записан правильно без ошибок.

0 голосов
/ 15 мая 2018

Если функция main завершается успешно, она возвращает 0 и любое другое значение в противном случае.Таким образом, строка return !is.eof() || !os; выполняет следующее:

EOF обозначает end of file.Итак, is.eof() проверяет, достигли ли мы конца файла.Если true, возвращается true or non 0, а false or 0 в противном случае.! приводит к результату inverse (причина - main для выхода с 0 в случае успеха).

То же самое относится и к os.Если os доступен для записи, он возвращает true и false в противном случае.И ! дает результат inverse.

, так что оба они должны выйти с 0.

0 голосов
/ 15 мая 2018

!is.eof() сообщает, достигнуто ли чтение из входного потока до конца файла (следовательно, выражение имеет значение true в случае проблемы чтения).

!os, который использует перегрузку ! оператор, верно в случае проблемы с записью.

0 голосов
/ 15 мая 2018
!is.eof()

возвращает, не являетесь ли вы в конце файла, который вы читаете (таким образом, true за отсутствие в конце и false за то, что он находится в конце) и

!os

возвращает, может ли ваш выходной файл не записываться. Другими словами, эта программа возвращает:

  1. true для случаев, когда вы не достигли конца вашего входного файла (независимо от 2.)
  2. true когда выходной файл недоступен для записи (независимо от 1.)
  3. false когда вы находитесь в конце файла, а выходной файл доступен для записи.
0 голосов
/ 15 мая 2018

легко, если вы разбиваете строки возврата, вы знаете, что он возвращает ненулевое значение для ошибки, так что это плюс.

!is.eof() || !os;

eof означает «конец файла», поэтому первая часть читает«если это не конец файла», вторая часть означает «если файла нет», так как вы пытались что-то сохранить в файл, отсутствие файла - ошибка.

, поэтому строкаможно прочитать:

return not(are we in the end of the file that we are reading?) 
    or not (the output file exists?)

, так что будет возвращено значение true, если входной файл завершен, а выходной файл существует, в противном случае - значение false.

...