error: variable length array of non-POD element type 'string' (aka 'basic_string<char>')

error: variable length array of non-POD element type 'string' (aka 'basic_string<char>')

我知道最终我需要将trigram,其中一个space包含前一个字符串中的3个字符,更改为一个动态数组来解决这个问题,但我一开始试图将我的数组容量设置得足够大.然而,当我编译我的代码时,错误出现了。

#error: variable length array of non-POD element type 'string' (aka 'basic_string<char>'#

代码:

//global variable
int CAPACITY = 1000;

int main()
{
    //a string that reads in the language of the text
string language = "";
    //a string that reads in the file name of the text
string filename = "text.txt";
    //a string that reads in the original text characters
string original = "";
    //a string that reads in the modified original array
string rid_of_spaces = "";
    //an array with capacity that stores the trigrams
string trigrams[CAPACITY];
ifstream finput;
char c;
    //the length of an array
int sLength = 0;
    //the tracker for trigrams
int counter = 0;

cin >> language >> filename;
finput.open(filename.c_str());

while (finput.get(c)){
            //to test if the character is alpha
    if (isalpha(c)){
                    //change the alphabet to lowercase
        c = tolower(c);
                    //store the modified letter in the array
        original += c;
    }
            //change any other characters into a space
    else original += ' ';
}
sLength = original.length();

    //loop through the original array and change mutiple spaces into one 
for (int i = 0; i < sLength; i++){
    if (isalpha(original[i]))
        rid_of_spaces += original[i];
    else {
        while (original[i] == ' ')
            i++;
        rid_of_spaces += ' ';
        rid_of_spaces += original[i];
    }
}
sLength = rid_of_spaces.length();

for (int i = 0; i < CAPACITY; i++)
    trigrams[i] = 0;//initialize each element to 0

for (int i = 0; i < sLength - 2; i++){
    trigrams[counter] += rid_of_spaces[i] 
            + rid_of_spaces[i + 1]
            + rid_of_spaces[i + 2];
        counter++;
}

cout << filename << endl;

cout << original << endl;
cout << rid_of_spaces << endl;

for (int i = 0; i < counter; i++)
    cout << trigrams[i] << endl;

finput.close();
return 0;

}

C++ 数组的大小必须是常量表达式。您将其声明为 int CAPACITY = 1000;,这不是常量表达式。添加 const 限定符可解决问题:int const CAPACITY = 1000;

但是,您应该避免使用纯数组。如果没有,请尝试使用 std::array if you know the size at compile time, or std::vector

变量CAPACITY不是编译时常量变量,C++中也没有变长数组(虽然有些人把它作为扩展名,但显然不是对所有类型都适用)。

您的问题有两种解决方案:

  1. 将变量转换为编译时常量,方法是将其设为 constexpr 或者 const(对于较旧的编译器),或者将其定义为预处理器宏。

  2. 使用std::vector,如std::vector<std::string> trigram(CAPACITY);

我的建议是您使用上面的 两种 解决方案,至少如果您以后需要调整向量的大小。如果大小将在编译时固定并且永远不会改变,那么使用第一个解决方案 使用 std::array 而不是 C 样式数组:

constexpr std::size_t CAPACITY = 1000;

...

std::array<std::string, CAPACITY> trigram;

变量

int CAPACITY = 1000;

应该是常数

const int CAPACITY = 1000; // or with c++11 constexpr int CAPACITY = 1000;  

对于

string trigrams[CAPACITY];

因为"ISO C++ forbids variable length array 'trigrams'"(g++ 消息)

还有这个

for (int i = 0; i < CAPACITY; i++)
    trigrams[i] = 0;//initialize each element to 0

应该是

for (int i = 0; i < CAPACITY; ++i)
    trigrams[i] = "";//initialize each element to 0

您没有"initialize [strings] to 0",但零长度 C 字符串。零长度 C 字符串不是无效的 0 指针,而是指向值为 0 的 char 的(有效)指针;

一般来说,如果有STL手段可以避免的话,最好不要使用C数组;对于 c++11,如果您想继续使用 "capacity large enough" 方法,std::array<std::string, CAPACITY> 在这里更可取。

live 在 Coliru 的

我在 for-loops 的头部冒昧地将所有 i++ 更改为 ++i;见例如。 What is the difference between ++i and i++ 背后的理由。

对于动态(没有预定义的边界)数组使用std::vector<std::string> trigrams;,

push_back or emplace_back 你的字符串到那个向量中, 对于 i- 迭代

for (std::size_t i = 0; i < trigrams.size(); ++i) {/* ... */}

或者使用std::vector的迭代器接口,例如

std::for_each(trigrams.begin(), trigrams.end(), 
              some_function_or_functor_that_does_the_job); 

(参见 std::foreach here),

或使用 c++11 只需

for (auto& s : trigrams) {/* ... */}

除非您需要像在第二个循环中那样自定义迭代。