C++ 在C+中读取作为操作码的文件输入+;

C++ 在C+中读取作为操作码的文件输入+;,c++,C++,我正在为学校的一个班级做一个项目。它是堆栈和队列的简单实现。然而,作为项目的一部分,我们需要从文件中读取操作码。操作码的格式如下所示: append 10 serve append 20 append 30 serve push 10 push 50 push 20 push 20 pop 我的问题是,当我通过标准的fstream读取文件时,它似乎接收到某种奇怪的格式或其他东西,并且与比较检查不匹配 我想知道我做错了什么,如何修复它,以及是否有更好的方法来操作操作码。事实上,if-else语句

我正在为学校的一个班级做一个项目。它是堆栈和队列的简单实现。然而,作为项目的一部分,我们需要从文件中读取操作码。操作码的格式如下所示:

append 10
serve
append 20
append 30
serve
push 10
push 50
push 20
push 20
pop
我的问题是,当我通过标准的fstream读取文件时,它似乎接收到某种奇怪的格式或其他东西,并且与比较检查不匹配

我想知道我做错了什么,如何修复它,以及是否有更好的方法来操作操作码。事实上,if-else语句总是指向if。有点迫切需要让它工作

#include "StackAndQueue.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

int main(){
    Stack leStack;
    Queue leQueue;

    //Read in the datafile. 
    cout << "Reading default file: p2datafile.txt";
        fstream data("p2datafile.txt");
        while (data.fail()){
                cout << " failed." << endl;
                data.close();
                cout << "Please enter path to datafile: ";
                string filename;
                cin >> filename;
                data.open(filename.c_str());
        }
        cout << endl << "Sucess!" << endl;

    //Loop through all the commands in the file
    while(!data.eof()){
        // Determine what kind of command is running 
        // and if parsing will be needed.

        string opcode;          
        getline(data,opcode,' ');

        if (opcode == "pop"){
            cout << "popping!" << endl;
            leStack.pop();
        }
        else if (opcode == "serve"){
            cout << "serving" << endl;
            leQueue.serve();
        }
        else if (opcode == "push"){
            cout << "pushing";
        }
        else{
            cout << "else!" << endl;
        }
    }
    data.close();

    system("pause");
    return 0;
}
#包括“StackAndQueue.h”
#包括
#包括
#包括
使用名称空间std;
int main(){
堆垛;
排队;
//读入数据文件。

以这种方式使用的cout
getline
仅将
'
视为分隔符,因此它不会在换行时停止;此外,您没有提取参数(当操作码有任何参数时),因此它将在下一次迭代中作为操作码读取(粘贴在实际操作码之前)

我认为,只要使用普通的<代码>操作符> <代码>,它就可以在任何空白处正确地停止(这就是你想要做的)并且正确地支持C++字符串。重要的是记住在需要时也提取参数(再次,用<代码>运算符> <代码>),在数字格式错误的情况下观察

istream::fail()
错误。在出现这些错误的情况下,您甚至可能希望出现流上升异常(这样它们就不会被忽略)

试试看
{
字符串操作码;
数据异常(ios::failbit);
//循环执行文件中的所有命令
while(数据>>操作码){
//确定正在运行的命令类型
//以及是否需要解析。
整型参数;
如果(操作码==“pop”){

以这种方式使用的cout
getline
仅将
'
视为分隔符,因此它不会在换行时停止;此外,您没有提取参数(当操作码有任何参数时),因此它将在下一次迭代中作为操作码读取(粘贴在实际操作码之前)

我认为,只要使用普通的<代码>操作符> <代码>,它就可以在任何空白处正确地停止(这就是你想要做的)并且正确地支持C++字符串。重要的是记住在需要时也提取参数(再次,用<代码>运算符> <代码>),在数字格式错误的情况下观察

istream::fail()
错误。在出现这些错误的情况下,您甚至可能希望出现流上升异常(这样它们就不会被忽略)

试试看
{
字符串操作码;
数据异常(ios::failbit);
//循环执行文件中的所有命令
while(数据>>操作码){
//确定正在运行的命令类型
//以及是否需要解析。
整型参数;
如果(操作码==“pop”){

cout您最可能遇到的问题源于您读取输入的方式。
std::getline(…,“”)
提取一个以空格结尾的字符串。对于给定的输入,获取的第一个字符串将是
append
,但第二个将是

10
serve
append
因为没有空间


那么,与其尝试准确地读入操作码,不如读入一行,看看是否能确定它是否以操作码开头。

您最可能遇到的问题来自于您读取输入的方式。
std::getline(…,“”)
提取以空格结尾的字符串。对于给定的输入,获取的第一个字符串将是
append
,但第二个字符串将是

10
serve
append
因为没有空间


那么,与其尝试准确地读入一个操作码,不如读一行,看看它是否以一个操作码开头。

与其一次一个字地读入文件,不如读整行(使用
std::getline
),然后使用
std::stringstream
来处理该行,如下所示:

     std::string line;
     while(std::getline(file,line))
     {
        std::stringstream linestream(std::stringstream::in|std::stringstream::out);
        linestream << line;
        std::string command;
        if(std::getline(linestream,command,' '))
        {
        //process line - chain 'if(std::getline(linestream,command,' '))' to advance the token steam
        }
        else
            //error blank line
     }
std::字符串行;
while(std::getline(文件,行))
{
std::stringstream linestream(std::stringstream::in | std::stringstream::out);

linestream不是一次一个字地读取文件,而是读取整行(使用
std::getline
),然后使用
std::stringstream
来处理该行,如下所示:

     std::string line;
     while(std::getline(file,line))
     {
        std::stringstream linestream(std::stringstream::in|std::stringstream::out);
        linestream << line;
        std::string command;
        if(std::getline(linestream,command,' '))
        {
        //process line - chain 'if(std::getline(linestream,command,' '))' to advance the token steam
        }
        else
            //error blank line
     }
std::字符串行;
while(std::getline(文件,行))
{
std::stringstream linestream(std::stringstream::in | std::stringstream::out);

linestream请您附加错误的输出好吗?(顺便说一句,去掉那个难看的系统(“暂停”);)标准流操作符会自动在空白处中断。但是您的getline()只在空格处中断(不是tab),所以请小心输入文件不包含tab(或使用操作符>>)。还有您的eof()测试不正确。eof标志在读取超过文件末尾之前不会设置为true。因此,如果读取整个文件(没有剩余内容),它仍将为false并进入循环。对getline()的下一次调用将失败,并使opcodde处于不确定状态(可能为“”,从而导致打印“else!”)。您可以附加错误的输出吗?(顺便说一句,摆脱那个难看的系统(“暂停”);)标准流操作符自动在空白处中断。但是您的getline()只在空白处中断(而不是tab),所以请小心输入文件不包含tab(或使用操作符>>)。还有您的eof()测试不正确。eof标志在读取超过文件末尾之前不会设置为true。因此,如果读取整个文件(没有剩余内容),它仍将为false并进入循环。对getline()的下一次调用将失败,并使opcodde处于不确定状态(可能为“”,从而导致打印“else!”)。还通过测试eof
而(!data.eof())
更容易声明linestream修复了此错误