繁体   English   中英

如何将类型从const char *转换为char *

[英]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.

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