c++ 枚举没有给出正确的值

xoefb8l8  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(78)

我一直在为我的命令行项目做一个简单的解释器,然而我最近偶然发现了一个问题,我不知道原因。
下面是代码:

// cls.h
#pragma once
#include <iostream>
#include <string>
#include <iomanip>

enum id {undef, kwd, idt, opr, val};    // Ignore idt

extern std::string keywords[];          // Declaring the keywords array
extern std::string operators[];         // Declaring the operators array

class Token
{
    id ID;
    std::string value;
public:
    Token() {
        ID = undef;
        value = "";
    }

    void SetID(id ID) {
        this->ID = ID;
    }

    void SetValue(std::string value) {
        this->value = value;
    }

    id GetID() {
        return ID;
    }

    std::string GetValue() {
        return value;
    }
};

std::string UserInput();
void Lexical(Token *token, int nstr, std::string str, int ntok);

// cls.cpp

#include <iostream>

// Definitions of the keywords and operators arrays
std::string keywords[] = {
                             "echo",
                             "exit"
                         };

std::string operators[] = {
                             "+",
                             "-",
                             "/",
                             "%" 
                          };

// input.cpp

#include "cls.h"

std::string UserInput()             // Function to take user's input
{
    std::string input;
    std::getline(std::cin, input);

    return input;
}

// lex.cpp

#include "cls.h"

// To check whether a token is a keyword
static bool aKeyword(std::string str)
{
    for (int i = 0; i < 10; i++) {
        if (keywords[i] == str)
            return true;
    }

    return false;
}

// To check whether a token is an operator
static bool aOperator(std::string str)
{
    for (int i = 0; i < 10; i++) {
        if (operators[i] == str)
            return true;
    }

    return false;
}

void Lexical(Token *token, int ntok, std::string str, int nstr)
{
    // Working the tokens' values
    int idx = 0;
    bool fspace = false;
    std::string plh[256];

    for (int i = 0; i < nstr; i++) {
        if ((str.at(i) == ' ') && (fspace == false)) {
            idx++;
            fspace = true;
            continue;
        } else
        if ((str.at(i) == ' ') && (fspace == true)) {
            continue;
        }

        plh[idx].append(&(str.at(i)), 1);
        fspace = false;
    }

    for (int i = 0; i < ntok; i++) {
        (token + i)->SetValue(plh[i]); 
    }

    // Working the tokens' IDs
    // Checking whether a token is a keyword, an operator or a value
    for (int i = 0; i < ntok; i++) {
        if (aKeyword((token + i)->GetValue()) == true) {
            (token + i)->SetID(kwd);
        } else
        if (aOperator((token + i)->GetValue()) == true) {       // <--- The problem
            (token + i)->SetID(opr);
        } else {
            (token + i)->SetID(val);
        }
    }

}

// init.cpp

#include "cls.h"

int main()
{
    std::string usinput;
    Token token[256];

    std::cout << "User input: ";
    usinput = UserInput();          // Taking user's input

    Lexical(token, 256, usinput, (int) usinput.size());   // Calling the lexical function

    // Outputting the tokens' values and IDs (The IDs is in the parentheses)
    for (int i = 0; i < 10; i++) {
        std::cout << "Token[" << i << "] = "
                  << token[i].GetValue()
                  << std::setfill(' ') 
                  << std::setw(15 - (token[i].GetValue()).size())
                  << "(" << token[i].GetID() << ")"
                  << std::endl;
    }

    return 0;
}

字符串
当Lexical函数尝试使用ID的关键字(kwd)、运算符(opr)或值(val)检查和分类标记时,问题出现在Lexical函数中。

enum id {undef, kwd, idt, opr, val};


很明显opr的值应该是3(表示运算符),但是当我试着运行程序并看到输出时,它给出的值是1(表示关键字)

benanthony@DESKTOP-QI9Q4LV:~/codes/CLine$ make
g++ init.cpp lex.cpp input.cpp cls.cpp -Wall -Wextra -o CLine
benanthony@DESKTOP-QI9Q4LV:~/codes/CLine$ ./CLine
User input: Hello there + - Rand - Lett - echo yes
Token[0] = Hello         (4)
Token[1] = there         (4)
Token[2] = +             (1)
Token[3] = -             (1)
Token[4] = Rand          (4)
Token[5] = -             (1)
Token[6] = Lett          (4)
Token[7] = -             (1)
Token[8] = echo          (1)
Token[9] = yes           (4)


token[2]、token[3]、token[5]和token[7]中的+和-应该具有ID值3。
我试着通过改变ID的名称来解决这个问题,但它仍然不起作用。
这道题看起来很简单,但我还是不知道该怎么做。是我遗漏了什么,还是我犯了什么错误?

xtfmy6hx

xtfmy6hx1#

这个问题是由aKeywordaOperator方法中的Undefined Behaviour引起的。你正在比较数组i < 10之外的字符串,如果你修复这些,你会得到预期的结果:

// To check whether a token is a keyword
static bool aKeyword(std::string str)
{
    for (int i = 0; i < 2; i++) {
        if (keywords[i] == str)
            return true;
    }

    return false;
}

// To check whether a token is an operator
static bool aOperator(std::string str)
{
    for (int i = 0; i < 4; i++) {
        if (operators[i] == str)
            return true;
    }

    return false;
}

字符串

相关问题