Передача потока чтения из файла в функцию C++

328
09 ноября 2017, 06:30

В общем, передаю поток чтения из файла в функцию, чтобы строку считала, но вадаёт ошибку:

char *readLine(ifstream in) {
    char *str = new char[1];
    char ch = 0;
    int i = 0;
    while ((ch = in.get()) != '\n' && (ch != '\0') {
        str[i++] = ch;
        char *copyStr = new char[i + 1];
        strncpy(copyStr, str, i);
        delete[] str;
        str = copyStr;
    }
    str[i] = '\0';
    return str;
}
int main() {
    ifstream in("input.txt");
    char *str = readLine(in);
    cout << str << '\n';
    in.close();
}

Ошибка:

/cygdrive/c/Users/garbart/Desktop/Labs/lab_6/main.cpp: In function 'int main()':
/cygdrive/c/Users/garbart/Desktop/Labs/lab_6/main.cpp:63:28: error: use of deleted function 'std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const std::basic_ifstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
     char *str = readLine(in);

Как это можно исправить и из-за чего это вообще происходит?

Answer 1

Вы пытаетесь передать ifstream по значению. А это значит, что нужно у объекта in вызвать конструктор копий. Но только у ifstream конструктор копий удален - копирование данного объекта может привести к сложным багам.

Что же делать? Передавать по ссылке или перемещать (std::move).

то есть, либо так исправить сигнатуру

char *readLine(ifstream& in)

либо вызывать так

char *str = readLine(std::move(in));

но только в этом случае закрытие файла бессмысленно (объект то уже перемещен!) и скорее всего приведет к ошибкам. Но файл и так будет закрыт при вызове деструктора.

P.S. возвращайте в функции std::string - Ваш код сильно упростится. Не нужны все эти "сишные приседания".

Answer 2

Потоки ввода-вывода владеют состоянием которое теряет смысл при копировании. К примеру, для ifstream таким состоянием будет текущая позиция в файле. Если ее скопировать - то после первой же операции ввода-вывода над одной из копий текущая позиция во второй копии устареет.

По этой причине потоки данных обычно передаются по ссылке:

char *readLine(ifstream &in) {

PS рекомендую вам использовать алгоритм экспоненциального роста буфера для строки - потому что сейчас у вас строка читается за время пропорциональное квадрату числа символов в ней (и это еще не считая скорости выделения памяти). А еще лучше - используйте std::string для тех же целей.

READ ALSO
Создание структур C++

Создание структур C++

Не очень понимаю, что я делаю не такПрограмма просто завершается (с кодом 0) и ничего не выводит

434
Ошибка [Error] expected primary-expression before &#39;}&#39; token

Ошибка [Error] expected primary-expression before '}' token

При компиляции выводит 10 48 [Error] expected primary-expression before '}' token Уже полчаса бьюсь, что делать?

318
Segmentation fault при использовании структуры addrinfo в sendto

Segmentation fault при использовании структуры addrinfo в sendto

Есть такая обёртка для подключения:

303
Чтение из COM порта С++

Чтение из COM порта С++

Есть такой код:

353