如何从文本文件中读取字符串并停止某个字符? C ++

时间:2014-10-21 02:15:14

标签: c++ encryption

我正在解密用我的加密程序制作的加密文件。我会尝试解释整个场景,这样每个人都能得到我的程序正在做的事情。

我的加密程序让用户输入一个字符串,然后将字符向右移动8到15之间的随机数。然后将加密文件发送到名为secret.dat的目的地

加密文件中的内容是

10rovvys1237123&5#10

它首先告诉你字符被移位的数字为(10),然后是加密的字符串(hello 123 123),空格使用空格前的字符并将该字符重叠4('y' '和'7')和'&'字符显示加密终止时。 '&'之后字符中的数字由“#”字符分隔,显示空格所在的位置。

首先使用解密程序,我使用ifstream打开文件并读取一个整数用作我向左移位加密它然后是我遇到问题的地方。我无法弄清楚如何将字符读成一个字符串直到'&'角色,这样我就可以将这些角色恢复正常。我找到了一种方法来获取它们,但我无法弄清楚如何将它们放入字符串中。

这就是我所做的,我能够把角色抓到'&'字符:

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

using namespace std;

int main()
{
    //Declare Variables
    int shift;
    char character;
    char endOfFile = '&';
    ifstream inData;

    //Open file
    inData.open("secret.dat");

    //Begin program
    inData >> shift;
    cout << shift << endl;

    inData.get(character);

    while(character != endOfFile)
    {
        if (character >= 'a' && character <= 'z')
        {
            character = ((character - 'a' - shift) % 26) + 'a';
        }
        if (character >= '0' && character <= '9')
        {
            character = ((character - '0' - shift) & 10) + '0';
        }
        cout << character;
        inData.get(character);
    }
    return 0;
}

我的第二个问题是我的公式,我正在使用它来移动角色,因为它似乎无法正常工作,因为我认为我需要做的就是更改我的加密公式,只是添加了shift减去shift。但这是一个不同的问题,主要问题是抓取字符并将它们放入一个字符串中,以便我以后可以使用它们。现在循环只是抓住每个字符然后把它放出去但是我不能访问循环外第一个字符以外的字符。

任何帮助都会非常感激,因为我似乎无法在其他任何地方找到我的解决方案。

2 个答案:

答案 0 :(得分:1)

您可以使用std :: getline从输入流读取字符串,直到某个字符/分隔符:)

// Assume your inData stream contains "10rovvys1237123&5#10"

int shift = 0;
std::string encrypted;

inData >> shift;
std::getline(inData, encrypted, '&');

// Here
// shift = 10
// encrypted = "rovvys1237123"

至于转回,只要你只是为每个字符添加一个整数值来移动你的字符串,你应该能够通过循环每个字符并减去相同的值来做相反的事情。类似的东西:

std::string decrypted = "";
for (auto& character : encrypted) {
    decrypted += character - shift;
}

答案 1 :(得分:0)

我将介绍另一种基于boost::spirit的方法,因为它将满足您的大部分需求。我在搜索解析器时发现了精神。文档很好而且全面,但可能需要花费成本(我刚刚开始,所以接受我作为可行性研究的答案,而不是作为精神可以做什么的真实参考)

动作是调用函数 parse_encr

int main()
{
    int my_shift;
    string encrypted_str("10rovvys1237123&5#10");

    bool success = parse_encr(encrypted_str.begin(),encrypted_str.end(),my_shift);
    cout    << "Parse Succeed ? "
            << (success ? "Yes":"no")
            << endl << "shift:" << endl
            << (success ? my_shift:0)
            << endl;

    cout << "Encrypted data are: " << str_buf.str() << endl;
    //...
}

结果是

Parse Succeed ? Yes
shift:
10
Encrypted data are: rovvys1237123

如何实现这一目标?使用Spirit(此处单击 qi :: phrase_parse ):

template <typename Iterator>
bool parse_encr(Iterator first, Iterator last,int & shift)
{
    bool r = qi::phrase_parse(
            first,
            last,
            qi::int_[boost::phoenix::ref(shift) = _1] >>
            qi::lexeme[ *qi::char_("a-zA-Z_ 0-9")[&cat_char<char>] ] >>
            qi::char_('&') >>
            qi::int_ >>
            qi::char_('#') >>
            qi::int_,
            qi::space
        );
    if (first != last) // fail if we did not get a full match
        return false;
    return r;
}

我会让你自己发现精神但很快就会解释:

通过使用规则qi :: int_指定等待int的事实。如果你正在等待角色'&amp;'你使用qi :: char('&amp;')。 你不需要qi :: lexeme,但我让它为这个例子(关闭空格跳过)

明星*表示一个或多个......

如果某些规则成功,您可以执行某项操作。该操作包含在方括号[]

之间

例如,第一个调用精神调用凤凰的另一个方面,允许您绑定到参数。第二个是对函数 cat_char

的调用
stringstream str_buf;

template <typename T>void cat_char(T & item)
{
    str_buf << item;
}

此方法功能更强大,因为您检查语法是否会获得不同的字段 它的。

一堆包含......所以你可以重播你身边的代码(你至少需要安装boost或boost标题......)

#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_char_class.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>


using namespace std;
using namespace boost::spirit;