简体   繁体   English

字符串向量push_back在类中失败

[英]string Vector push_back failing in class

I have a class with a method that should return a vector of strings. 我有一个类,其方法应该返回一个字符串向量。 the getCommVector method has to push_back the elements of a string array into a string vector that can then be returned by the method. getCommVector方法必须将一个字符串数组的元素推回一个字符串向量,然后可以由该方法返回。 When trying to add a string element to the string vector i get: 当我尝试将字符串元素添加到字符串向量时,我得到:

libc++abi.dylib: terminate called throwing an exception
2Program ended with exit code: 0

I cannot understand why I can't push_back strings to the vector. 我无法理解为什么我不能将push_back字符串传递给向量。 Any ideas? 有任何想法吗? Thanks in advance! 提前致谢!

code segments of interest (edited after suggestions): 感兴趣的代码段(根据建议编辑):

class Command {
public:
    //Command (std::string, bool, bool);
    void setOperators(std::string,bool, bool);
    void analyseCommand();
    Command();
    std::vector<std::string> getCommVector ();
private:
    int numOperators; //number of total commands
    int opCount; //current command number
    std::string input_string;
    bool field_command, byte_command;
    std::string commVector[3];
    std::vector<std::string> finalCommVector;
    void byte_analysis();
    void field_analysis();
    void decode_command();
    void syntax_error();
    void decode_error();
};


Command::Command() : numOperators(0), opCount(0),  field_command(false),byte_command(false)
{

}
std::vector<std::string> Command::getCommVector ()
{
    std::string s ="test";
    finalCommVector.push_back("s");
    return finalCommVector;
}

adding SSCE: 添加SSCE:

class Command {
    public:
        //Command (std::string, bool, bool);
        void setOperators(std::string,bool, bool);
        void analyseCommand();
        Command();
        std::vector<std::string> getCommVector ();
    private:
        int numOperators; //number of total commands
        int opCount; //current command number
        std::string input_string;
        bool field_command, byte_command;
        std::string commVector[3];
        std::vector<std::string> finalCommVector;
        void byte_analysis();
        void field_analysis();
        void decode_command();
        void syntax_error();
        void decode_error();

};


Command::Command() : numOperators(0), opCount(0), field_command(false),byte_command(false)
{

}

void Command::syntax_error()
{
    std::cout<<"Incorrect Syntax Error: Usage: linuxcut -b num -f num \n";
    exit(EXIT_FAILURE);
}

void Command::decode_error()
{
    std::cout<<"Decode Error: Usage: linuxcut -b num -f num \n";
    exit(EXIT_FAILURE);
}


void Command::analyseCommand()
{
    if (byte_command) {
        //start byte command analysys
        byte_analysis();
    }
    else if (field_command)
    {
        //start field command analysys
        field_analysis();
    }
}




void Command::setOperators(std::string input_argument, bool is_field, bool is_byte)
{
    input_string = input_argument;

    field_command = is_field;
    byte_command = is_byte;
}

std::vector<std::string> Command::getCommVector ()
{

    std::string s = "ssd";
    finalCommVector.push_back(s);
    /*
    for (int i = 0; i<sizeof(commVector); i++)
    {

        if (commVector[i] != "")
        {
            //debug

            std::cout<<"asdas";
        }


    }
     */
    return finalCommVector;
}


void Command::byte_analysis()
{
    int next_state = 0;
    int dashCount = 0;
    int commVectIndex = 0;




    //iterate through string and check if the argument is valid
    for (int i= 0; i<input_string.length(); i++) {



        switch (next_state) {
            case 0: //start
                //if character is a number:
                if (isdigit(input_string.at(i)))
                {
                    //first elemnt of command commVector is number
                    commVector[commVectIndex]+=input_string.at(i);

                    //DEBUG
                    std::cout<<commVector[commVectIndex];
                    next_state = 1;
                }
                //if character is a dash:
                else if (input_string[i] == '-')
                {
                    //increment dashCount
                    dashCount++;
                    //if next character in input_string is a number continue
                    if (isdigit(input_string[i+1])) {
                        commVector[commVectIndex]+=input_string.at(i);
                        commVectIndex++;
                        next_state = 1;
                    }
                    else //else error
                    {
                        syntax_error();
                    }
                }
                //if it's niether: error!
                else
                {

                    syntax_error();
                }
                break;

            case 1:
                //if next character is a number:
                if (isdigit(input_string[i]))
                {
                    commVector[commVectIndex]+=input_string.at(i);
                    next_state = 1;
                }
                //if next character is dash
                else if (input_string[i] == '-'&& dashCount <= 3)
                {
                    dashCount++;
                    //increment commandVectIndex
                    commVectIndex++;
                    next_state = 2;
                    commVector[commVectIndex]+=input_string.at(i);
                    //increment commandVectIndex to accomodate next operation
                    commVectIndex++;
                }

                //if it's niether: error!
                else
                {

                    syntax_error();
                }
                break;

            case 2://previous character was dash
                //if next character is number
                if (isdigit(input_string[i]))
                {
                    commVector[commVectIndex]+=input_string.at(i);
                    next_state = 1;
                }

                //if it's niether: error!
                else
                {

                    syntax_error();
                }
                break;

            default:
                syntax_error();
                break;
        }

    }

}



void Command::field_analysis()
{

}
/*****************FUNCTIONS DEFINITIONS***************/

void print_usage() {
    std::cout<<"Incorrect Syntax Error: Usage: linuxcut -b num -f num \n";
}



/*****************END OF FUNCTIONS DEFINITIONS***************/


/***************** MAIN ***************/

int main(int argc, char *argv[]) {
    int opt= 0;
    std::string byte = "-1-2,2",field = "";
    std::string sub_arg_delimiter = ","; //delimiter for comma serparated arguments
    static bool complement = false;
    int diffOpt = 0; //stores the difference between optind  and argc to read filenames in command
    std::string fileName;
    //Specifying the expected options
    //The two options l and b expect numbers as argument
    static struct option long_options[] = {
        {"byte",      required_argument,       0,  'b' },
        {"field", required_argument,       0,  'f' },
        {"complement",    no_argument, 0,  0 },
        {0,           0,                 0,  0   }
    };

    Command testCommand;
    testCommand.setOperators("-2-", false, true);

    std::vector<std::string> trial = testCommand.getCommVector();


    std::cout<<"filename:"<<fileName<<std::endl;
    std::cout<<"Selected flags:\n"<< "b: "<< byte<<"\nf: "<<field<<"\ncomplement: "<<complement<<std::endl;


    return 0;
}

You're iterating way beyond the array size. 您正在迭代超出数组大小的方式。 sizeof(commVector) returns the size of the array in bytes. sizeof(commVector) 以字节为单位返回数组的大小

If you have C++11 available, you can do this: 如果您有可用的C ++ 11,则可以执行以下操作:

for (const auto &s : commVector) {
  if (s != "") {
    // as before
  }
}

Or at least this (if you only have partial C++11 support): 或者至少这个(如果你只有部分C ++ 11支持):

for (auto it = std::begin(commVector); it != std::end(commVector); ++it) {
  std::string s = *it;
  // the rest as before
}

Without C++11, you can at least do this: 没有C ++ 11,您至少可以执行以下操作:

for (int i = 0; i < sizeof(commVector) / sizeof(commVector[0]); ++i) {
  // the rest as before
}

Or provide your own function for obtaining the correct array size: 或提供您自己的函数以获得正确的数组大小:

template <class T, size_t N>
size_t arraySize(const T (&)[N]) { return N; }

// Use:

for (size_t i = 0; i < arraySize(commVector); ++i) {
  // the rest as before
}
i<sizeof(commVector);

should be 应该

i<countof(commVector);

if countof/_countof is defined for your compiler. 如果为编译器定义了countof / _countof。 If not, you can do it yourself, it is typically defined as: 如果没有,您可以自己完成,通常定义为:

#define countof(a) (sizeof(a)/sizeof(a[0]))

and I won't go into discussion about using macros in C++ :) 我不会讨论在C ++中使用宏:)

Of course, you could also use a constant are your array has fixed number of elements, but I guess it's just an example. 当然,你也可以使用常量,你的数组有固定数量的元素,但我想这只是一个例子。

sizeof returns the size of the object (in this case the string array) itself, not the count of elements inside the vector. sizeof返回对象的大小(在本例中为字符串数组)本身,而不是向量内的元素数。

Because of this, it is equal to number of the array elements multiplied by size of a single string instance, so you try to access non-existing items with operator[] . 因此,它等于数组元素的数量乘以单个字符串实例的大小,因此您尝试使用operator[]访问不存在的项。

This is also broken: 这也坏了:

finalCommVector.push_back("s"); 

and probably you meant: 可能你的意思是:

finalCommVector.push_back(s);

If all you need is the array of std::string commVector as a std::vector<String> , you can use std::vecor::assign : 如果你需要的是std::string commVector数组作为std::vector<String> ,你可以使用std::vecor::assign
finalCommVector.assign(commVector, commVector+3)
The '3' is the length of you array. '3'是数组的长度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM