Ошибка C ++ C2512 пытается использовать ifstream для чтения файла в классе, Visual Studio 2008 - PullRequest
0 голосов
/ 22 января 2019

По общему признанию, я новичок в 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 выдает мне следующие 2 ошибки:

1 ошибка C2512 : 'std :: basic_istream <_Elem, _Traits>': соответствующий конструктор по умолчанию недоступен строка 21

2 ошибка C2059 : синтаксическая ошибка: ']' строка 137

Помощь оценена, а оскорбления терпимы, спасибо:)

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Следуя рекомендациям @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;
}
0 голосов
/ 22 января 2019

Ваш класс использует std::istream для члена inputfile, но не инициализирует его.Это не сработает.

В этой ситуации вашему классу нужно будет использовать std::ifstream вместо своего inputfile члена, а затем вызвать его open() метод перед попыткой чтения из него.

Кроме того, ваш метод reader() игнорирует элемент inputfile, вместо этого создавая локальную переменную с тем же именем для чтения.Вам нужно избавиться от этой локальной переменной и вместо этого вызвать open() для вашего члена класса.

...