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

C++ 如何从文本文件中读取字符串并在某个字符处停止?C++;,c++,encryption,C++,Encryption,我正在解密用我的加密程序制作的加密文件。我将尝试解释整个场景,以便每个人都了解我的程序到底在做什么 我的加密程序让用户输入一个字符串,然后将字符右移8到15之间的随机数。然后它将加密文件发送到名为secret.dat的目标 它在加密文件中读取的内容是 10rovvys1237123&5#10 它首先告诉您将字符移位为(10)的数字,然后是加密字符串(hello 123 123),空格使用空格之前的字符,并将该字符移位4(“y”和“7”),“&”字符显示加密何时终止。在“&”字符之后,有

我正在解密用我的加密程序制作的加密文件。我将尝试解释整个场景,以便每个人都了解我的程序到底在做什么

我的加密程序让用户输入一个字符串,然后将字符右移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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
//声明变量
int移位;
字符;
char endOfFile='&';
Iftream inData;
//打开文件
inData.open(“secret.dat”);
//开始程序
因达塔>>班次;

cout我将介绍另一种基于的方法,因为它将满足您的大多数需求。我在搜索解析器时发现了spirit。文档很好,很全面,但可能需要花费一些时间来适应(我只是刚刚开始,所以我的回答只是一个可行性研究,而不是作为使用spirit可以做什么的真正参考)

操作是调用函数parse_encr

如何实现这一点?使用Spirit(这里只需调用qi::短语\u parse):

模板
bool parse_encr(迭代器优先、迭代器最后、int和shift)
{
bool r=qi::短语解析(
第一,
最后,,
qi::int_uu[boost::phoenix::ref(shift)=\u1]>>
qi::lexeme[*qi::char(“a-zA-Z_u0-9”)[&cat_char]]>>
qi::char_u2;('&')>>
qi::int\u>>
qi::char_uz('#')>>
齐:国际,,
齐:空间
);
if(first!=last)//如果我们没有得到完全匹配,则失败
返回false;
返回r;
}
我会让你们自己发现灵魂,但很快就会解释:

您可以通过使用规则qi::int\指定正在等待int的事实。如果正在等待字符'&',则使用qi::char('&')。 您不需要qi::lexeme,但在本例中我允许使用它(关闭空格跳过)

星号*表示一个或多个

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

例如,第一个调用spirit call phoenix的另一个方面,它允许您绑定到一个参数。第二个是调用函数cat_char

stringstream str_buf;
模板无效目录字符(T&item)
{

str_buf您可以使用std::getline从输入流读取到字符串中,最多读取一个特定的字符/分隔符:)

至于向后移位,只要您只是在每个字符上添加一个整数值来移位字符串,您应该能够通过循环遍历每个字符并减去相同的值来实现相反的操作。类似于:

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

您可能想阅读,它允许您停止阅读任何指定字符,而不仅仅是换行符(顾名思义)。并允许追加,因此您可以在循环中追加字符。或者,如果使用
std::getline
函数,则在输入后对字符串进行迭代并进行转换。最后,您应该考虑如果输入文件的格式不正确,或者从中读取时出错,会发生什么情况。现在,您将得到一个infinite loop.Ya,如果文件无法读取,我会添加进去,但我会把它放在最后。我真是个白痴,哈哈。我一直在尝试使用getline,但一直收到一条错误消息,我无法理解,现在才发现这是因为我使用的是“cin”而不是“inData”xD。非常感谢。
Parse Succeed ? Yes
shift:
10
Encrypted data are: rovvys1237123
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;
}
stringstream str_buf;

template <typename T>void cat_char(T & item)
{
    str_buf << item;
}
#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;
// 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;
}