C ++ File help, Шифрование и дешифрование строки - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь сделать простую программу, которая изменяет значения на 3 (функция шифрования) -> Я хочу, чтобы это напрямую влияло на файл. Но я не уверен как. После того, как он зашифрован, я вызову функцию расшифровки (которая работает именно так, как я хочу). Таким образом, вам нужно будет запустить программу для доступа к дневнику. Есть ли в любом случае, я могу изменить отдельные символы, как я делаю в функции расшифровки? Я продолжаю получать ошибку getline.

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

void decrypt_diary(string,string);
void encrpyt_diart(string,string);

int main()
{
    string fileName = "Diary.txt";
    string line;
    decrypt_diary(fileName,line);
    return 0;
}
void decrypt_diary(string fileName, string line)
{
    ifstream journal;
    journal.open(fileName);
    if (journal.is_open())
    {
        while (getline(journal,line))
        {
            for (int i=0; i<signed(line.length()); i++)
            {
                line[i] = line[i] + 3;
            }
            cout << line << endl;
        }
    }
    journal.close();
}

void encrypt_diary(string fileName, string line)
{
    ofstream journal;
    journal.open(fileName);
    if (journal.is_open())
    {
        while (getline(journal,line))
        {
            for (int i=0; i<signed(line.length()); i++)
            {
                line[i] = line[i] - 3;
//              journal << line[i];
            }
            cout << line << endl;
        }
    }
    journal.close();
}

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Так что, если я правильно понимаю, что вы хотите, вы хотите просмотреть файл, символ за символом и заменить его другим символом.Я снова скажу, что переход от символа к символу, вероятно, не лучшая идея, но модификация кусков должна быть достаточно простой.

#include <string>
#include <fstream>
#include <iostream>

inline void encrypt_char(char& in) {
    in += 3;
}

inline void decrypt_char(char& in) {
    in -= 3;
}

int main(int argc, char** argv) {
    //These first 2 lines just process the command line argument
    if (argc < 2 || (argv[1][0] != 'e' && argv[1][0] != 'd') || argv[1][1] != '\0') return 1;
    bool encrypt_mode = (argv[1][0] == 'e' ? true : false);
    std::fstream file("Diary.txt", std::ios::in | std::ios::out);
    file.seekg(0, std::ios::end);
    size_t size = file.tellg(); //This should tell us the file size
    char c;
    for (size_t i = 0; i < size; i++) {
        file.seekg(i, std::ios::beg); //Set read position
        file.read(&c, 1); //Read a character
        if (encrypt_mode) encrypt_char(c);
        else decrypt_char(c);
        file.seekp(i, std::ios::beg); //Set write position
        file.write(&c, 1); //Write a character
    }
    file.close();
    return 0;
}

Обратите внимание, что мы избегаем использования >> и << по мере их форматирования, пропускаем пробелы по умолчанию (хотя вы можете это изменить) и т. Д. Вместо этого мы используем read и write, так какони просто хранят байты, какими бы они ни были.

Этот подход означает, что мы выполняем множество операций над файлом и, вероятно, не самый быстрый.Вместо этого вы можете прочитать в блоках, что изменение довольно просто, просто замените символ массивом символов и прочитайте больше чем 1 байт за один раз.Однако, если это возможно, проще всего прочитать весь файл за один раз.

#include <string>
#include <fstream>
#include <iostream>

inline void encrypt_char(char& in) {
    in += 3;
}

inline void decrypt_char(char& in) {
    in -= 3;
}

int main(int argc, char** argv) {
    //These first 2 lines just process the command line argument
    if (argc < 2 || (argv[1][0] != 'e' && argv[1][0] != 'd') || argv[1][1] != '\0') return 1;
    bool encrypt_mode = (argv[1][0] == 'e' ? true : false);
    std::fstream file("Diary.txt", std::ios::in | std::ios::out);
    file.seekg(0, std::ios::end);
    size_t size = file.tellg(); //This should tell us the file size
    file.seekg(0, std::ios::beg);
    char* fileData = new char[size]; //Don't need null-termination
    file.read(fileData, size); //Read the whole file
    for (size_t i = 0; i < size; i++) { //Process the characters
        if (encrypt_mode) encrypt_char(fileData[i]);
        else decrypt_char(fileData[i]);
    }
    file.seekp(0, std::ios::beg); //Find the start of the file
    file.write(fileData, size); //Write the whole thing
    delete[] fileData;
    file.close();
    return 0;
}

Вызов программы с ./myProgram e вызывает ее шифрование, а замена e на d вызывает ее дешифрование.

Мы не использовали здесь строки, поскольку они нам на самом деле не нужны, но вы всегда можете сделать это, если предпочитаете строки массивам символов.

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

0 голосов
/ 10 сентября 2018

Вы имеете в виду ошибку getline?

. / Main.cpp: 41: 36: ошибка: нет соответствующей функции для вызова getline (std :: ofstream &, std :: __ cxx11 :: string &) ’ while (getline (журнал, строка)

Если это так, я считаю, что проблема в том, что нет функции getline () , которая принимает объект ofstream , так как getline () предназначена для чтения файлы, в то время как ofstream (поток выходных файлов) предназначен для записи файлов. Он отлично работает в функции decrypt_diary , поскольку он принимает ifstream (поток входных файлов) .

Если вы сосредоточитесь на реализации либо дешифрования, либо шифрования в первую очередь, вам будет легче решать проблемы компиляции.

Вы можете попробовать закомментировать функцию encrypt_diary (string fileName, string line) , затем попытаться скомпилировать и снова запустить программу.

Я думаю, вы обнаружите, что ваша decrypt_diary (string fileName, string line) прекрасно работает.

...