[英]How convert type from const char * to char *
我正在嘗試用C ++創建簡單的應用程序。 此應用程序必須從文件中讀取並顯示數據。 我寫的功能:
std::vector <AndroidApplication> AndroidApplication::getAllApp(){
std::vector<AndroidApplication> allApp;
std::fstream f;
f.open("freeApps.txt");
std::string line;
if(f.is_open()){
while(getline(f, line)) {
std::string myLine = "";
char * line2 = line.c_str();
myLine = strtok(line2,"\t");
AndroidApplication * tmpApp = new AndroidApplication(myLine[1], myLine[2], myLine[4]);
tmpApp->Developer = myLine[0];
tmpApp->Pop = myLine[3];
tmpApp->Type = myLine[5];
allApp->pushBack(tmpApp);
}
}
return allApp;
}
它引發了我的錯誤:
myLine = strtok(line2,"\t");
一個錯誤:
無法從'const char *'轉換為'char *'
你能告訴我怎么處理它?
不要使用strtok
。 std::string
有自己的字符串掃描功能,例如find
。
要使用strtok,您需要一個可寫的字符串副本。 c_str()返回一個只讀指針。
你不能只是“轉換它”而忘記它。 從.c_str()
獲得的指針是一個只讀緩沖區 。 你需要將它復制到一個新的緩沖區來處理:理想情況下,首先要避免使用像strtok
這樣的過時函數。
(實際上,我不太確定你在使用這種標記化做什么;你只是在一次標記化的字符串中索引字符,而不是索引標記。)
您還混淆了動態和自動存儲。
std::vector<AndroidApplication> AndroidApplication::getAllApp()
{
std::vector<AndroidApplication> allApp;
// Your use of fstreams can be simplified
std::fstream f("freeApps.txt");
if (!f.is_open())
return allApp;
std::string line;
while (getline(f, line)) {
// This is how you tokenise a string in C++
std::istringstream split(line);
std::vector<std::string> tokens;
for (std::string each;
std::getline(split, each, '\t');
tokens.push_back(each));
// No need for dynamic allocation here,
// and I'm assuming you wanted tokens ("words"), not characters.
AndroidApplication tmpApp(tokens[1], tokens[2], tokens[4]);
tmpApp.Developer = tokens[0];
tmpApp.Pop = tokens[3];
tmpApp.Type = tokens[5];
// The vector contains objects, not pointers
allApp.push_back(tmpApp);
}
return allApp;
}
我懷疑錯誤實際上是在前一行,
char * line2 = line.c_str();
這是因為c_str()
給出了一個指向字符串內容的只讀指針。 沒有標准的方法可以從C ++字符串中獲取可修改的C風格字符串。
從字符串中讀取空格分隔單詞的最簡單選項(假設您正在做的事情)是使用字符串流:
std::vector<std::string> words;
std::istringstream stream(line);
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(),
back_inserter(words));
如果你真的想使用strtok
,那么你需要一個字符串的可寫副本,帶有C風格的終結符; 一種方法是將其復制到一個向量中:
std::vector<char> writable(line.c_str(), line.c_str() + line.length() + 1);
std::vector<char *> words;
while (char * word = strtok(words.empty() ? &writable[0] : NULL, " ")) {
words.push_back(word);
}
請記住, strtok
很難正確使用; 你需要為每個令牌調用一次,而不是一次創建一個令牌數組,並確保在你完成字符串之前沒有其他任何東西(比如另一個線程)調用它。 我不確定我的代碼是完全正確的; 我很久沒有嘗試過使用這種特殊形式的邪惡了。
既然你要求它:
從理論上講,您可以使用const_cast<char*>(line.c_str())
來獲取char*
。 但是將結果賦予strtok
(修改其參數)是IIRC無效的c ++(你可以拋棄constness,但你可能不會修改const對象)。 所以它可能適用於您的特定平台/編譯器(即使它工作,它可能會隨時中斷)。
另一種方法是創建一個副本,其中填充了字符串的內容(和可修改的):
std::vector<char> tmp_str(line.begin(), line.end());
myLine = strtok(&tmp_str[0],"\t");
當然,正如其他答案非常詳細地告訴你的那樣,你真的應該避免在c ++中使用像strtok
這樣的函數來支持直接在std::string
上工作的函數(至少除非你已經牢牢掌握了c ++,高性能要求並且知道使用c-api函數在特定情況下更快(通過分析))。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.