【问题标题】:invalid conversion from 'char' to 'char*' using strcpy使用 strcpy 从 'char' 到 'char*' 的无效转换
【发布时间】:2011-11-26 09:57:32
【问题描述】:

好的,这是我遇到问题的代码部分:

char * historyArray;
historyArray = new char [20];

//get input
cin.getline(readBuffer, 512);       
cout << readBuffer <<endl;

//save to history
for(int i = 20; i > 0; i--){
    strcpy(historyArray[i], historyArray[i-1]); //ERROR HERE//  
}

strcpy(historyArray[0], readBuffer); //and here but it's the same error//

我收到的错误是:

"invalid conversion from 'char' to 'char*' 
           initializing argument 1 of 'char* strcpy(char*, const char*)'

该项目是创建一个psudo OS Shell,它将捕获和处理中断以及运行基本的unix命令。我遇到的问题是我必须将过去的 20 个命令存储到一个在堆栈上动态分配的字符数组中。 (也被解除分配)

当我只使用二维字符数组时,上面的代码可以正常工作:

char historyArray[20][];

但问题是它不是动态的......

是的,我知道 strcpy 应该用于复制字符串。

任何帮助将不胜感激!

【问题讨论】:

    标签: c++ char strcpy


    【解决方案1】:

    两种解决方案。第一个是如果你出于某种原因真的想要数组,另一个更推荐使用std::strings 并且更“C++”。

    char * historyArray[20]; // Create an array of char pointers
    
    // ...
    
    historyArray[i] = new char[SIZE]; // Do this for each element in historyArray
    

    那么你可以在historyArray中的元素上使用strcpy

    推荐我重复的第二个解决方案(我已经修复了一些其他问题):

    string historyArray[20];
    
    getline(cin, readBuffer); // Make readbuffer an std::string as well
    cout << readBuffer << endl;
    
    for(int i = 19; i > 0; i--){ // I think you meant 19 instead of 20
        historyArray[i] = historyArray[i-1];
    }
    
    historyArray[0] = readBuffer;
    

    【讨论】:

    • 他的意思不是 1 而不是 0,他的意思是 19 而不是 20。
    【解决方案2】:
    char * historyArray;
    historyArray = new char [20];
    
    //get input
    cin.getline(readBuffer, 512);       
    cout << readBuffer <<endl;
    
    //save to history
    for(int i = 20; i > 0; i--){
       strcpy(&(historyArray[i]), &(historyArray[i-1])); //ERROR HERE//  
    }
    
    strcpy(historyArray, readBuffer); //and here but it's the same error//
    

    但这只会修复编译器错误,而不是代码中的逻辑错误。您使用 C++ 所以字符串解决方案:

    vector<string> history;
    
    cin.getline(readBuffer,512);
    
    history.push_back(readBuffer);
    

    或者,如果您想要一个包含 readBuffer 中所有内容的长字符串:

    string history;
    
    cin.getline(readBuffer,512);
    history = history += string(readBuffer);
    

    例如...

    【讨论】:

      【解决方案3】:
      strcpy(&historyArray[i], &historyArray[i-1]);
      

      数组表示法提供引用,而 strcopy 需要指针。使用地址 (&) 运算符将引用转换为指针。

      【讨论】:

        【解决方案4】:

        停止在 C++ 程序中使用 C 习语:

        std::deque<std::string> historyArray;
        
        //get input
        std::string readBuffer;
        std::getline(std::cin, readBuffer);       
        std::cout << readBuffer << std::endl;
        
        //save to history
        historyArray.push_front(readBuffer);
        if(historyArray.size() > 20)
          historyArray.pop_back();
        

        因此,我们有:

        • readBuffer / getline() 中没有缓冲区溢出威胁
        • 在任何地方都没有让我们感到困惑的指针。
        • 没有超出范围的数组
        • 任意长的输入字符串
        • 久经考验的内存分配语义

        【讨论】:

        • 谢谢!我的教授对项目作业的措辞使全班大多数人相信他希望我们使用原生 C 字符串。我和他谈过,他说他不在乎。
        • 不客气。请帮自己一个忙——在未来来自课堂作业或其他学习练习的问题中,请添加“家庭作业”标签。这样做有助于像我这样的人不要脱口而出答案(就像我在这里所做的那样。)在带有“家庭作业”标签的问题中,人们会更加小心地解释他们的逻辑和推理,而不仅仅是提供答案。
        【解决方案5】:

        错误 1:当 i 设置为 20 时,您的索引超出了数组边界。

        错误 2:historyArray[i] 是 char,而不是 char *。你需要 &historyArray[i]。

        【讨论】:

        • 那解决不了问题。他需要存储多个字符串,但他只有一个 char 数组。将&amp; 运算符添加到参数将尝试复制具有未定义行为的重叠字符串。
        • 是的,你是对的。我读的太快了。但是在他将historyArray转换为指针数组或使用向量后,他仍然需要修复我列出的错误。
        • 基思是正确的。不过,很好地抓住了越界访问。请注意,他确实访问了两次historyArray[0]
        【解决方案6】:

        historyArray[i] 是一个字符。它是单个字符。你想用刺。您的根本问题是 historyArray 是 char* 这意味着它指向包含字符的内存范围。你希望它是一个char**,它是一个指向字符串指针的指针。您的初始化代码将是

        char** historyArray;
        historyArray = new char* [20];
        for (int i = 0; i < 20; i++)
        {
            historyArray[i] = new char [512];  //Big enough to have a 512 char buffer copied in
        }
        

        【讨论】:

          【解决方案7】:

          historyArray 指向 20 个chars 的数组(的第一个元素)。您只能在该数组中存储一个字符串。

          在 C 中,您可以创建一个 char** 对象并让它指向 char* 对象数组的第一个元素,其中每个元素都指向一个字符串。这就是 main()argv 参数所做的。

          但是由于您使用的是 C++,因此使用 vectorstrings 并让库为您进行内存管理会更有意义。

          【讨论】:

            猜你喜欢
            • 2017-04-15
            • 2014-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-09
            • 2017-03-19
            • 1970-01-01
            相关资源
            最近更新 更多