C ++ Как читать из произвольного текстового файла - PullRequest
0 голосов
/ 13 марта 2020

У меня есть проект, в котором я должен читать из текстового файла и кодировать его содержимое, используя книжный шифр. Первым шагом, который я предполагаю, будет чтение из двух текстовых файлов и подсчет номеров страниц / строк / столбцов (номера страниц определяются разделителем «\ f», а строки определяются «\ n»). Однако я не хочу, чтобы пользователю приходилось каждый раз переименовывать свой файл в «message.txt», чтобы файл мог быть прочитан. Есть ли в любом случае программа на C ++ для чтения любых текстовых файлов, введенных пользователем?

Код моей текущей тестовой программы:

#include <iostream>     // Basic I/O
#include <string>       // string classes
#include <fstream>      // file stream classes
#include <sstream>      // string stream classes
#include <locale>       // locale class
using namespace std;



// version 0
int main() {
    while (!cin.eof()) {
        char ch;
        cin >> ch;
        cout << ch;
    }
}

Она получает все из файла и выводит его правильно, однако таким образом, я могу принять только один входной файл. Я надеялся, что смогу сделать что-то вроде этого:

int main( int argc, char* argv[])

так:

argv[0] = program name
argv[1] = book cipher
argv[2] = message file
argv[3] = output file (encoded message goes here)

Есть ли версия C ++ этого? Я попытался прочитать ifstream (argv [1]), который не сработал, как я ожидал, и выдал исключение. Я чувствую, что char * argv [] - это то, что используется в C, но не в C ++, поскольку в C ++ есть строка, а строки не являются массивом char, как в C. Хотите знать, кто-нибудь может написать мне пример, просто чтобы посмотреть, как работает синтаксис для этого в C ++.

И какую функцию ввода я могу использовать для подсчета управляющих символов, таких как '\ n' и '\ f'? Я знаю из Java, я мог бы использовать charAt () и сделать это в al oop или в C, это просто массив символов. Ввод вводит в заблуждение меня в C / C ++, я буду продолжать смотреть на учебники о том, как работают эти различные функции. Любые идеи будут оценены.

1 Ответ

1 голос
/ 13 марта 2020

Ваше понимание параметров main argc и argv в основном правильно. То, что вы будете использовать в качестве аргументов строки команды, будет именем файлов.

Чтобы работать с ними, вам нужно открыть файлы с заданными именами файлов, после чего вы сможете извлечь данные. Чтобы открыть входной файл, вы можете использовать std::ifstream и использовать его конструктор, в котором вы передаете имя файла. Логическое! Оператор для std::fstream был перезаписан и будет возвращать состояние (результат) операции. Поэтому вы можете написать if (fileStream), чтобы проверить, была ли операция открытия успешной.

Для подсчета чего-то существует много возможностей. Вы можете использовать стандартные алгоритмы.

Пожалуйста, посмотрите пример кода ниже:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <algorithm>


int main(int argc, char* argv[]) {

    // Check if the number of parameters are correct
    if (4 != argc) {
        // Wrong number of arguments, inform the user
        std::cerr << "\n*** Wrong comand line parameters: please call with:\n"
            << "encode cipherFileName messageFileName outputFileName\n\n";
    }
    else
    {
        // Now, try to open all files. Open cipher file and check if this worked
        if (std::ifstream cipherFileStream(argv[1]); cipherFileStream) {

            // Open message file and check, if that worked
            if (std::ifstream messageFileStream(argv[2]); messageFileStream) {

                // And Open output file and check, if that worked
                if (std::ofstream outputFileStream(argv[3]); outputFileStream) {

                    // Read the complete message file into one string
                    std::string messageData(std::istreambuf_iterator<char>(messageFileStream), {});
                    // Count some special charcters in the message file
                    size_t newLines = std::count(messageData.begin(), messageData.end(), '\n');
                    size_t formFeeds = std::count(messageData.begin(), messageData.end(), '\f');

                    // Show result to user
                    std::cout << "\nNew lines:  " << newLines << "\nForm feeds: " << formFeeds << "\n";

                }
                else {
                    std::cerr << "\n*** Error: Could not open output file\n";
                }
            }
            else {
                std::cerr << "\n*** Error: Could not open message file\n";
            }
        }
        else {
            std::cerr << "\n*** Error: Could not open book cipher file\n";
        }
    }
    return 0;
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...