2012-06-14 49 views
0

我有這樣的代碼:必須有常量的值在Visual C++

std::string name = "kingfisher"; 
char node_name[name.size()+1]; 
strcpy(node_name,name.c_str()); 
node_name[name.size()] = '\0'; 

它在DEVC++運行良好,但在Visual C++中,我得到了一個名爲 「name.size()必須是恆定值」 的問題!如何解決問題?我知道我必須在node_name的聲明中使用const值,但有時(如上面的情況)我不能!謝謝!

+2

爲什麼不讓'node_name'也是'std :: string'? – iammilind

+2

這樣做後,你用'node_name'做了什麼?有可能所有這些都可以避免,但很難說如果不知道你在用'node_name'做什麼。 –

+0

我可以向你建議你習慣於在最大警告水平上編譯嗎?其中一人會在DevC++中使用GCC時提醒您,這是不正確的,當您完成後,您可以確信它可以在任何符合標準的編譯器上工作。 – chris

回答

4
char node_name[name.size()+1]; 

作爲name.size()值不是在編譯時已知,在上述的聲明,node_name是可變長度數組未在ISO C允許的(VLA)++。

在DevC++中,它編譯和工作,因爲它提供了作爲擴展的VLA功能,這在編譯配置中啓用。

使用std::string,或char *new[]/delete[],無論適合您需要一起。

你的具體情況,也就是說,如果你知道該字符串字面不已,那麼你可以這樣寫:

char node_name[] = "kingfisher"; //this works great! 

但是,如果字符串值是不知道,你想它從某處複製,然後這樣做:

char *node_name = new char[name.size()+1]; 
std::strncpy(node_name, name.c_str(), name.size()+1); //use strncpy 

//work with node_name 

//must deallocate the memory 
delete []node_name; //not `delete node_name;` 

使用std::strncpy代替std::strcpy,因爲前者需要緩衝大小也作爲第三個參數,如上所示,而後者沒有(這是不安全的,通常,在此情況雖然)。

+0

爲什麼在DevC++中,這不是問題! –

+1

@Kingfisher:因爲DevC++使用gcc,在這方面它不遵循C++標準。 –

+1

@Kingfisher:您正在使用DevC++中的編譯器特定擴展名(gcc?)。 – Naveen

3

變長數組不是標準C++的一部分。您需要在編譯時提供大小。運行時會發生name.size()。評論應該足以解釋幻數或常數。

char node_name[11]; //length of "kingfisher" + null 

如果你不知道在編譯時字符串的長度(但你在你的例子做),你可以使用一個動態數組,在謝里夫的回答解釋得非常好。

+0

我知道它,但我想使用node_name [name.size()+ 1],因爲我將我的程序從DevC++移動到VSC++!任何其他建議?! –

+0

@Kingfisher,沒有編譯器擴展的唯一方法是通過其他答案中提到的其中一種方法在運行時動態分配內存。 – chris

+0

@Kingfisher:我想知道爲什麼你需要'char'數組。你的代碼片段已經使用'std :: string'。你在調用一些需要'char *'的API嗎? – Blastfurnace

0

其大小在運行時確定的陣列稱爲可變長度陣列VLA。 VLA是C99中的一項功能。一些C++編譯器支持它們作爲擴展,有些則不支持;聽起來像你的Visual C++版本沒有。

您總是可以動態地分配node_namenew,而不是在堆棧上。

2

有很多選擇:

std::string name = "kingfisher"; 
char* node_name = alloca(name.size() + 1); 
strcpy(node_name, name.c_str()); 
// no need to explicitly set the '\0' - strcpy copies it too 
...OR... 
char* node_name = new char[name.size() + 1]; 
strcpy(node_name, name.c_str()); 
...OR... 
char* node_name = strdup(name.c_str()); // allocate on malloc/free/realloc "C" heap 
...OR... 
std::vector<char> node_name(name.data(), name.data() + name.size()); // sans '\0' 
...OR... 
std::vector<char> node_name(name.c_str(), name.c_str() + name.size() + 1); // with '\0' 
...OR... 
std::string node_name = node; // do something with node_name.c_str()/.data() etc. 

注:儘管歐內斯特的「不要在C++中使用malloc(),使用新的[]」關於Stefan的刪除答案評論,可能有必要 - 例如,當傳遞指向可能重新分配或釋放內存的C代碼的指針時。

0

我的第一種方法是查看你使用的數組,並詢問是否有更好的方法。

如果你真的需要這個數組,我會建議一個矢量:它是動態大小的,但不需要刪除。

std::string name = "kingfisher"; 
    std::vector<char> name_buff(name.begin(), name.end()); 
    name_buff.push_back(0); // nul-terminate 
    char *node_name = &name_buff[0]; 
    // ... 
相關問題