【问题标题】:strcpy() causes invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]strcpy() 导致从“const char*”到“char*”的无效转换 [-fpermissive]
【发布时间】:2014-07-30 21:17:50
【问题描述】:

我试图让一个名为PReader 的对象(带有一个名为Execute() 的函数,不带参数)通过构造函数传入一个文件名,以便Execute() 可以访问它。我尝试设置它的方式涉及让构造函数为字符串分配内存,然后将其复制过来,并为其设置析构函数。我知道这很尴尬,但我知道这种设置将使我的项目的未来添加更容易。

这是我的对象当前的设置方式:

#include <PReader.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

PReader::PReader(const char *f)
{
    filename = new char[strlen(f)+1];
    strcpy(filename, f);
}

PReader::~PReader()
{
    delete [] filename;
}

void PReader::Execute(void)
{
    FILE *f = fopen(this->filename, "rb");
    ...
}

这给了我错误:

PReader.C: In constructor ‘PReader::PReader(char*)’:
PReader.C:10:20: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
  strcpy(filename, f);
                    ^
In file included from /usr/include/stdlib.h:11:0,
                 from PReader.C:2:
/usr/include/string.h:30:8: error:   initializing argument 1 of ‘char* strcpy(char*, const char*)’ [-fpermissive]
 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));

对于这么几行代码,我有点惊讶我在这里遗漏了一些东西。我可以做些什么来确保转换成功?

编辑:PReader.h:

#include "source.h"

#ifndef PREADER_H
#define PREADER_H

class PReader : public Source
{
    public:
        const char* filename;
        PReader(const char *filename);
        virtual ~PReader();
        virtual void Execute();
};

#endif

【问题讨论】:

  • 请在您的问题中包含来自PReader.hPReader 的类定义。
  • 还有什么是filename
  • 添加了PReader.hfilenameconst char*
  • 帮宇宙(和你)一个忙,使用 std::string

标签: c++ constructor constants destructor strcpy


【解决方案1】:

这两个声明是有区别的

const char * filename;

char * const  filename;

第一个声明指向const char 类型的常量对象的指针。指针本身可以更改为例如++filename,但指针指向的对象可能不会更改为例如++*filename。所以你不能在函数std::strcpy中使用这样的指针作为第一个参数。

第二个声明了一个指向非常量对象的常量指针。所以指针本身可能不会改变。例如,编译器将针对表达式++filename 发出错误。但是您可以更改指针指向的对象。例如++*filename; 这样的指针可以用作函数std::strcpy 中的第一个参数。

最后你可以定义指向非常量对象的非常量指针

char * filename;

在这种情况下,您可以更改指针本身并更改指针指向的对象。

所以在你的类中,你应该将文件名定义为

char * const  filename;

或作为

char * filename;

考虑到指针可以定义为

const char * const  filename = "String Literal";

也就是这条语句定义了一个指向常量对象的常量指针。您既不能更改指针本身,也不能更改指针指向的对象。

等价的声明是

const char * constexpr  filename = "String Literal";

【讨论】:

    【解决方案2】:

    您似乎将filename 定义为const char*。改为char*,这样您就可以实际修改它(使用strcpy):

    char* filename;
    

    或者更好,既然这是 C++,为什么不使用 std::string 呢?

    【讨论】:

    • 谢谢,解决了。我猜只是出于旧的(坏的)C 习惯使用 char 数组。
    【解决方案3】:

    在你的标题中,你有

    const char* filename;
    

    而你正试图 strcpy 进入它。这是不允许的。将其更改为

    char* filename;
    

    【讨论】:

      猜你喜欢
      • 2016-01-20
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      相关资源
      最近更新 更多