C ++错误C2512尝试使用ifstream读取类在Visual Studio 2008中的文件

时间:2019-01-22 01:52:43

标签: c++ constructor ifstream

我承认我是C ++的极端新手,所以请原谅我可能非常幼稚的问题。

我正在编写代码,该代码应该解析汇编语言文件的基本部分,然后在第二阶段将其翻译为机器语言。

我已经建立了一个parser类,但是在打开外部程序集.asm文本文件并将其提供给构成我的parser类的各种函数方面没有成功。

尤其是,构造函数存在问题。 我附上我在下面编写的完整代码:

// parses .asm assembly files
#include <iostream>
#include <fstream>
#include <varargs.h>
#include <string>
using namespace std;

class parser
{
private:
    istream inputfile;
    char inputname[30];
    string line;
    bool endfile;
    bool a_command, l_command, c_command; 
    string parsedLine, destParsedLine, compParsedLine, jumpParsedLine;
public:
    // default parser constructor
    parser()
    {
    }

    //parser(char* argv[])
    //{
    //  reader(argv[]);
    //}

    // opens input file
    string reader(char* argv[])
    {
        strcpy(inputname,argv[1]);
        strcat(inputname,".asm");
        // opens input .asm file
        ifstream inputfile(inputname);
        // reads first line
        getline(inputfile,line);
        if (line[0] == '/' || line.empty())
            inputfile.ignore(line.length(),'\n');
        return line;
    }

    // checks if at end file
    bool hasMoreCommands()
    {
        a_command = false;
        l_command = false;
        c_command = false;
        endfile = false;
        if (inputfile.eof())
            endfile = true;         
        return endfile;
    }

    // advances read of inputfile
    void advance()
    {
        if (line[0] == '/' || line.length() == 0)
            inputfile.ignore(line.length(),'\n');
        getline(inputfile,line);
    }

    /* function for labelling the type of command (address,computation,label) */
    bool commandType()
    {
        if (line[0] == '@')
            a_command = true;
        else if (line[0] == '(')
            l_command = true;
        else
            c_command = true;
        return a_command, l_command, c_command;
    }

    // function to select parsing function
    string selector()
    {
        if (a_command || l_command)
            symbol();
        else if (c_command)
        {
            dest();
            comp();
            jump();
            string parsedLine = destParsedLine + compParsedLine + jumpParsedLine;
        }
        return parsedLine;
    }

    // function returning address or label symbol
    string symbol()
    {
        if (a_command)
            string parsedLine = line.substr(1);
        else if (l_command)
            string parsedLine = line.substr(1,line.length()-1);
        return parsedLine;
    }

    // functions returning computation destination
    string dest()
    {
        size_t equal = line.find('='); //no '=' found = returns 'npos'
        string destParsedLine = line.substr(0,equal);
        return destParsedLine;
    }
    string comp()
    {
        size_t equal = line.find('=');
        size_t semicolon = line.find(';');
        string compParsedLine = line.substr(equal,semicolon);
        return compParsedLine;
    }
    string jump()
    {
        size_t semicolon = line.find(';');
        string jumpParsedLine = line.substr(semicolon);
        return jumpParsedLine;
    }
};

// main program
int main (int argc, char *argv[])
{
    bool endfile = false;
    string parsedLine;
    int count = 0;

    if ((argc != 2) || (strchr(argv[1],'.') != NULL))
    {
        cout << argv[0] << ": assembly .asm file argument should be supplied, without .asm extension\n";
        return 1;
    }

    parser attempt1 = parser();
    attempt1.reader(argv[]);
    while (!endfile)
    {
        attempt1.hasMoreCommands();
        if (endfile)
            return 0;
        if (count > 0)
            attempt1.advance();
        attempt1.commandType();
        attempt1.selector();
        cout << parsedLine << endl; //debugging purposes
        count++;
    }
}

我通过命令行提供了要打开的.asm文本文件的名称({.asm文件位于此cpp文件的同一文件夹中)。

因此,我需要使用varargs.h,我想这可能是问题的一部分。

当我尝试构建它时,Visual Studio 2008给我以下两个错误:

  

1错误 C2512 :'std :: basic_istream <_Elem,_Traits>':没有合适的默认构造函数可用第21行

     

2错误 C2059 :语法错误:']'第137行

感谢您的帮助,并且可以忍受侮辱,谢谢:)

2 个答案:

答案 0 :(得分:0)

您的类对std::istream成员使用inputfile,但不对其进行初始化。那是行不通的。

在这种情况下,您的类将需要使用std::ifstream代替其inputfile成员,然后在尝试从其读取之前调用其open()方法。

此外,您的reader()方法将忽略inputfile成员,而是创建一个具有相同名称的本地变量以供读取。您需要摆脱该局部变量,而要在类成员上调用open()

答案 1 :(得分:0)

遵循@Remy Lebeau的建议,下面的修改后的代码至少可以正确编译(尽管仍然无法实现其应有的功能)

// parses .asm assembly files
#include <iostream>
#include <fstream>
#include <varargs.h>
#include <string>
using namespace std;

class parser
{
private:
    istream inputfile;
    char inputname[30];
    string line;
    bool endfile;
    bool a_command, l_command, c_command; 
    string parsedLine, destParsedLine, compParsedLine, jumpParsedLine;
public:
    // default parser constructor
    parser()
    {
    }

    // ignores inputfile line if comment or empty
    void ignoreline()
    {
        if (line[0] == '/' || line.empty())
            inputfile.ignore(line.length(),'\n');
    }

    // composes inputfile name and opens input file
    void reader(char* argv[])
    {
        strcpy(inputname,argv[1]);
        strcat(inputname,".asm");
        // opens input .asm file
        inputfile.open(inputname, fstream::in);
        // reads first line
        getline(inputfile,line);
        ignoreline();
    }

    // checks if at end file
    bool hasMoreCommands()
    {
        a_command = false;
        l_command = false;
        c_command = false;
        endfile = false;
        if (inputfile.eof())
            endfile = true;         
        return endfile;
    }

    // advances read of inputfile
    void advance()
    {
        ignoreline();
        getline(inputfile,line);
    }

    /* function for labelling the type of command (address,computation,label) */
    bool commandType()
    {
        if (line[0] == '@')
            a_command = true;
        else if (line[0] == '(')
            l_command = true;
        else
            c_command = true;
        return a_command, l_command, c_command;
    }

    // function to select parsing function
    string selector()
    {
        if (a_command || l_command)
            symbol();
        else if (c_command)
        {
            dest();
            comp();
            jump();
            string parsedLine = destParsedLine + compParsedLine + jumpParsedLine;
        }
        return parsedLine;
    }

    // function returning address or label symbol
    string symbol()
    {
        if (a_command)
            string parsedLine = line.substr(1);
        else if (l_command)
            string parsedLine = line.substr(1,line.length()-1);
        return parsedLine;
    }

    // functions returning computation destination
    string dest()
    {
        size_t equal = line.find('='); //no '=' found = returns 'npos'
        string destParsedLine = line.substr(0,equal);
        return destParsedLine;
    }

    string comp()
    {
        size_t equal = line.find('=');
        size_t semicolon = line.find(';');
        string compParsedLine = line.substr(equal,semicolon);
        return compParsedLine;
    }

    string jump()
    {
        size_t semicolon = line.find(';');
        string jumpParsedLine = line.substr(semicolon);
        return jumpParsedLine;
    }
};

// main program
int main (int argc, char *argv[])
{
    bool endfile = false;
    string parsedLine;
    int count = 0;

    if ((argc != 2) || (strchr(argv[1],'.') != NULL))
    {
         cout << argv[0] << ": assembly .asm file argument should be supplied, without .asm extension\n";
        return 1;
    }

    parser attempt1 = parser();
    attempt1.reader(argv);
    while (!endfile)
    {
        attempt1.hasMoreCommands();
        if (endfile)
            return 0;
        if (count > 0)
            attempt1.advance();
        attempt1.commandType();
        attempt1.selector();
        cout << parsedLine << endl;
        count++;
    }
    return 0;
}