Читатель и писатель файлов

Мне сказали, что следующий мой код был написан плохо. Насколько плохо? У вас есть какие-нибудь рекомендации?


#include <iostream>
#include <fstream>

void ioMenu(std::ifstream&, std::ofstream&, std::string&, std::string&);
int ioMenuChoice();
void fileOpener(std::ifstream&, std::ofstream&, std::string&, int&);
void fileReader(std::ifstream&, std::string&);
void fileWriter(std::ofstream&);
void fileOpenAndRead(std::ifstream&, std::ofstream&, std::string&, std::string&);
void fileCreateAndWrite(std::ifstream&, std::ofstream&, std::string&);
void readAndWrite(std::ifstream&, std::ofstream&, std::string&, std::string&);

int main() {

    std::string     fileName    {};
    std::string     reader      {};
    std::ifstream   inputFile   {};
    std::ofstream   outputFile  {};

    ioMenu(inputFile, outputFile,fileName,reader);
}

void ioMenu(std::ifstream& inputFile, std::ofstream& outputFile, std::string& fileName, std::string& reader) {

    switch (ioMenuChoice()) {

        case 1:
            fileOpenAndRead(inputFile, outputFile, fileName, reader);
            break;
        case 2:
            fileCreateAndWrite(inputFile, outputFile, fileName);
            break;
        case 3: 
            readAndWrite(inputFile, outputFile, fileName, reader);

    }
}

int ioMenuChoice(){

    int choice {};
    
    std::cout << "1. Read from filen2. Output to Filen3. Bothn4. Exitn";
    std::cin >> choice;

    while (choice < 1 || choice > 4){
        std::cout << "nInvalid input. Please re-enter a number from 1 to 3 : ";
        std::cin >> choice;
    }

    return choice;
}


void fileOpener(std::ifstream& inputFile, std::ofstream& outputFile, std::string& fileName, int choice) {           // Grab / Open file

    // Grab file name
    std::cout << "Please enter the directory and file name : Example : C:\Users\Alex\Desktop\numbers.txt : ";
    std::cin >> fileName;
    

    if (choice == 1) {

        inputFile.open(fileName);

        while (inputFile.fail()) {
            std::cout << "Invalid input. Please re-enter the directory and file name : Example : C:\Users\Alex\Desktop\numbers.txt : ";
            std::cin >> fileName;
            inputFile.open(fileName);
        }
    }
    else {

        outputFile.open(fileName);

    }
}

void fileReader(std::ifstream& inputFile, std::string& reader) {                // Read from file

    while (inputFile >> reader) {   

        std::cout << reader;

    }

    inputFile.close();
}

void fileWriter(std::ofstream& outputFile) {

    std::string outputString("");
    std::cout   << "What would you like to write to the file? ";
    std::cin    >> outputString;
    outputFile  << outputString;

    outputFile.close();
}

void fileOpenAndRead(std::ifstream& inputFile, std::ofstream& outputFile, std::string& fileName, std::string& reader) {

    fileOpener(inputFile, outputFile, fileName, 1);
    fileReader(inputFile, fileName);

}

void fileCreateAndWrite(std::ifstream& inputFile, std::ofstream& outputFile, std::string& fileName) {

    fileOpener(inputFile, outputFile, fileName, 2);
    fileWriter(outputFile);

}

void readAndWrite(std::ifstream& inputFile, std::ofstream& outputFile, std::string& fileName, std::string& reader) {

    fileOpenAndRead(inputFile, outputFile, fileName, reader);
    fileCreateAndWrite(inputFile, outputFile, fileName);

}

edit: Вот готовый код, извините. Главное, что я ищу, — правильно ли я использую функции (у каждой есть своя роль?

1 ответ
1

Ну первое, что выскакивает, это то, что нет const по любому из параметров.

void fileOpener(std::ifstream&, std::ofstream&, std::string&, int&);

например, 3-й и 4-й параметры являются «выходными» параметрами? Это означает, что функция изменит string и int в копии звонящего. Тем не менее, это void так почему бы не обеспечить результат обычным способом?

Отсутствие имен параметров также делает менее понятным, что делают эти функции и как их использовать.

    std::string     fileName    {};
    std::string     reader      {};
    std::ifstream   inputFile   {};
    std::ofstream   outputFile  {};

Тебе не нужно {} после всего этого, поскольку у них есть конструкторы по умолчанию.

В main функция продолжается с
ioMenu(inputFile, outputFile,fileName,reader);

и ничего больше. Итак, если это все «исходящие» параметры, что вы делаете с результатами?


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

Набор функций должен быть записан как класс с этими 4 значениями в качестве данных экземпляра.

Например

class Putter {
    std::string     fileName;
    std::string     reader;
    std::ifstream   inputFile;
    std::ofstream   outputFile;
    void fileOpener();
    void fileReader();
    void fileWriter();
    void fileOpenAndRead();
    void fileCreateAndWrite();
    void readAndWrite();
public:
    void run();  // something like that.  What you have in `main` goes here.
};

  • Спасибо. Я довольно начинающий программист, теперь я понимаю, что мне следует использовать const во всех моих параметрах, передаваемых по ссылке, если я не планирую изменять их значения. Насколько я понимаю, все массивы передаются как ссылка, поскольку это указатель на первый элемент, поэтому всякий раз, когда я создаю параметр функции с массивом, должен ли я помещать перед ними константу? благодаря.

    — d8 Александр

  • @ d8Alexander Я уверен, что в наши дни быть новичком может быть ошеломляюще! Есть кое-что, что нужно сказать о начале работы с примитивными системами. Так держать. Повторные массивы: передача «массива» (на самом деле указателя на первый элемент) — это вещь C, а не то, что вы обычно должны делать. Напишите свои функции, которые нужно взять итераторы и работать с любым классом коллекций, не ограничиваясь массивами. …

    — JDłuosz

  • … OTOH, наиболее эффективный внутренний код действительно может работать напрямую с непрерывной последовательностью в памяти; использовать gsl :: span для этого. И поскольку я поднял этот вопрос, обязательно изучите документ «Стандартные рекомендации», на который есть ссылка.

    — JDłuosz


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *