Мне сказали, что следующий мой код был написан плохо. Насколько плохо? У вас есть какие-нибудь рекомендации?
#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 ответ
Ну первое, что выскакивает, это то, что нет 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