【问题标题】:iostream reads a couple of lines correctly then fails on subsequent linesiostream 正确读取了几行,然后在后续行中失败
【发布时间】:2015-04-20 01:03:01
【问题描述】:

我正在为类创建一个程序,用于加密和解密一个简单的文本文件。在设置 iostreams 之前,我能够让程序使用简单的用户输入 (cin/cout)。我努力让 iostreams 工作,最后确实弄明白了——主要是。我遇到麻烦的地方是我的测试文件有多行。它可以很好地读取和翻译前两行,但在第二行之后,我得到的只是乱码。我认为这可能与行尾的回车和换行符的某种怪癖有关,但是我很困惑为什么它从第一行到第二行工作,而不是在第二到第三行及以后。我的代码如下。目前我最好的猜测是问题存在于从第 123 行开始的循环中。但我还不能隔离。

如果有人能抽出几分钟时间来看看,我非常感谢您抽出宝贵的时间!不过,请尽量只为我指出正确的方向,而不建议对我的其余代码进行太多更改。这是家庭作业,需要尽可能多地成为我的工作。我将证明我得到了帮助以使其正常工作。

如果您想对此进行测试,请在运行此解决方案的目录中创建一个名为 C++Test.txt 的文件,并将一些测试文本放入其中以供阅读。同样,它似乎适用于第 1 行和第 2 行,但在第 2 行之后失败。

#include <iostream>
#include<string>
#include<iomanip>
#include<cstring>
#include<fstream>
using namespace std;
inline void keep_window_open() { char ch; cin>>ch; }


char cipher(char, int, char, int);
char calculation(int);
void encrypt();
void decrypt();
void displayMenu(void);
void getMenuSelection(int);

int main (void)
{
bool running=true;
char answer=' ';

cout<<
    "Use this program to encrypt/decrypt text.\nPlease select an option\n";
while (running==true)                   //allows program to loop until user
{                                       //user selects to exit
    displayMenu();                      //function call
    cout<<
        "\nWould you like to start over?\n(enter Y for Yes or N for No)\n";
    cin>>answer;
    if (answer=='Y'||answer=='y')
    {
        running=true;
    }
    else
    {
        running=false;
    }
}
cout<<"\nGoodbye.";



//The next two lines stop the Command Prompt window from closing
//until the user presses a key, including Enter.
cout    << "\nPress enter twice to exit." << endl;
cin.ignore(2);
}
///////////////////////////////Width Guage//////////////////////////////////////
///////////////////////////////displayMenu//////////////////////////////////////
//This function simply displays the menu and calls getMenuSelection()
void displayMenu(void)
{
int userInput=0;
cout<< "\nPlease select an option:\n(Enter 1, 2, or 3)\n" ;
cout<< "1. Encrypt\n" ;
cout<< "2. Decrypt\n" ;
cout<< "3. Exit\n";
cin>>userInput;
if (userInput==1||userInput==2)
{
    getMenuSelection(userInput);            //function call

}
else
{

}


}
///////////////////////////////Width Guage//////////////////////////////////////
///////////////////////////////getMenuSelection/////////////////////////////////
void getMenuSelection(int userInput)
{
   switch (userInput)
   {
    case 1:
          {
                 encrypt();
                  break;
          }
    case 2:
          {
                 decrypt();
                  break;
          }
   }
}
///////////////////////////////Width Guage//////////////////////////////////////
///////////////////////////////encrypt//////////////////////////////////////////
void encrypt()
{
char key[128]={' '}, mess[256]={' '};
string newMess;
int keyLength=0, messLength=0, switchChar=0, i=0;
cout<<"What is the encryption key?\n(128 characters or less only)";
cin>>key;
keyLength=strlen(key);
cin.ignore(300,'\n');
cout<<"Getting message file C++Test.txt\n";
ifstream message;                   //Opens input stream to get C++Test.txt
message.open("C++Test.txt", ifstream::in);
int j=0;                            //loop counter
do                                  //loop to input from file
{
    mess[j]=message.get();
    j++;
}
    while (message.good());
message.close();                    //closes input stream


messLength=strlen(mess);
int k=0;
for (int counter=0;counter<messLength;counter++)
{
    if (isalpha(mess[counter]))
    {
        if (i>keyLength)
        {
            i=0;
        }
        else if (i==keyLength-1)
        {
            newMess.push_back(cipher(mess[counter],keyLength,key[i],
                switchChar));
            i=0;
        }
        else
        {
            newMess.push_back(cipher(mess[counter],keyLength,key[i],
                switchChar));
            i++;
        }
    }
    else
    {
        newMess.push_back(mess[counter]);
        i++;
    }



}
filebuf newMessagefb;
    newMessagefb.open("C++TestDecrypt.txt", ios::out);
    ostream newMessage (&newMessagefb);
    newMessage<<newMess;
    newMessagefb.close();
    k++;
cout<<"The encrypted message is:\n\n"<<newMess;

}
///////////////////////////////Width Guage//////////////////////////////////////
///////////////////////////////cipher///////////////////////////////////////////
char cipher (char origMessChar, int keyLength, char origKeyChar, int switchChar)
{
origMessChar=tolower(origMessChar);
origKeyChar=tolower(origKeyChar);
switch (switchChar)
{
case 0://for encryption
    {
        int messNum=origMessChar-'a';
        int keyNum=origKeyChar-'a';
        char newMessChar=((messNum+keyNum)%26)+'a';
        return (newMessChar);
    }
case 1://for decryption
    {
        int messNum=origMessChar-'a';
        int keyNum=26-(origKeyChar-'a');
        char newMessChar=((messNum+keyNum)%26)+'a';
        return (newMessChar);
    }
}
}
///////////////////////////////Width Guage//////////////////////////////////////
///////////////////////////////decrypt//////////////////////////////////////////
void decrypt()
{
char key[128]={' '}, mess[256]={' '};
string newMess;
int keyLength=0, messLength=0, switchChar=1, i=0;
cout<<"What is the encryption key?\n(128 characters or less only)";
cin>>key;
keyLength=strlen(key);
cin.ignore(300,'\n');
cout<<"Getting message file C++TestDecrypt.txt\n\n";
ifstream message;                   //Opens input stream to get C++Test.txt
message.open("C++TestDecrypt.txt", ifstream::in);
int j=0;                            //loop counter
do                                  //loop to input from file
{
    mess[j]=message.get();
    j++;
}
    while (message.good());
message.close();                    //closes input stream
messLength=strlen(mess);
for (int counter=0;counter<messLength;counter++)
{
    if (isalpha(mess[counter]))
    {
        if (i>keyLength)
        {
            i=0;
        }
        else if (i==keyLength-1)
        {
            newMess.push_back(cipher(mess[counter],keyLength,key[i],
                switchChar));
            i=0;
        }
        else
        {
            newMess.push_back(cipher(mess[counter],keyLength,key[i],
                switchChar));
            i++;
        }
    }
    else
    {
        newMess.push_back(mess[counter]);
        i++;
    }
}
cout<<"The encrypted message is:\n\n"<<newMess;
}     

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    问题在于您读取字符/字符串的方法。

    如果你替换你的:

    do
    {
        mess[j]=message.get();
        j++;
    }
    while (message.good());
    

    用这个:

    do                                  //loop to input from file
    {
        message >> mess[j];
        j++;
    }
    while (message.good());
    message.ignore();
    

    您的程序现在将正确读取每个字符。

    但是,请注意,如果输入包含多行,则处理字符/字符串的方式存在轻微缺陷。 我不完全知道你想要的行为是什么,但你应该做出相应的改变。

    我上面提到的修改后的代码,不会读取endline \n 字符。

    因此,您必须再次调整以使用 2D char 数组或字符串数​​组而不是 char。

    我会建议你使用 string 而不是 char(你也可以像 char 数组一样遍历字符串,例如 string[0] string[1] 等),然后使用 getline 读取每一行。例如:

    string mess[256];
    do                                  //loop to input from file
    {
        getline(message,mess[j]);
        j++;
    }
    while (message.good());
    

    希望对你有帮助。

    【讨论】:

    • 这确实有帮助。谢谢!经过一番浏览后,我开始认为问题可能出在程序读取文本的方式上。我只是不明白为什么。仍然不确定我是否完全理解,但会玩弄你的建议,看看我是否能弄清楚。再次感谢指点!
    • 嗨,你是对的。 c++ iostream 或 fstream 读取文本的方式有点棘手。例如使用 cin >> string 和 getline(cin,string) 的组合将导致由 endline 引起的一些错误行为。你必须玩并继续尝试 C++ 读取文本的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2020-04-09
    相关资源
    最近更新 更多