如何将 `const char *` 转换为简单的 `char *`?

发布于 2024-11-07 11:26:25 字数 827 浏览 0 评论 0原文

我正在使用 pdCurses 库,并且目标是仅在我的 C++ 控制台游戏中真正使用字符串,但curses mvinstr() 函数或任何插入函数都需要非常量 char * 作为参数。

  • 我最初解决这个问题的方法是简单地输入 string.c_str() ,但这会返回一个 const char * ,显然它没有使用该函数。
  • 接下来我放置 (char *)string.c_str() 但这只会导致未处理的异常。
  • 最后,我刚刚尝试了 char *test = string.c_str() 但这也不与 const 兼容。

我该怎么做才能解决这个问题?

K 我刚刚尝试了 const_cast() ,但仍然抛出异常并中断...... 我不知道为什么 PDcurses 只接受非常量 char 指针.... =(

好吧,当我使用这段代码时,制作 char* 缓冲区不起作用(time_s 是刺):

size_t length; 
    char buffer[12]; 
    length=time_s.copy(buffer,5,0); 
    buffer[length]='\0';
mvinstr(time_loc_y, time_loc_x, buffer);

我什至在 mvinstr( )并检查缓冲区的内容为“00 /0” 正是我想要的。

但我得到了“xutility”的访问冲突点......

I'm using the pdCurses library and am aiming to only really use strings in my C++ console game but the curses mvinstr() function or any insert function requires a non-const char * as a parameter.

  • My solution at first to this problem was simply entering in string.c_str(), but that returns a const char * which apparently doesn't work with the function.
  • Next I put (char *)string.c_str() but this only causes an unhandled exception.
  • Finally I just tried char *test = string.c_str() but that's not compatible with const either.

What do I do to solve this?

K i just tried const_cast() and i still get an exception thrown and break....
I don't know why PDcurses only takes non-const char pointers.... =(

alright making a char* buffer didn't work when i used this code (time_s is the sting):

size_t length; 
    char buffer[12]; 
    length=time_s.copy(buffer,5,0); 
    buffer[length]='\0';
mvinstr(time_loc_y, time_loc_x, buffer);

i even put a stop before mvinstr() and checked the buffer's contents which was "00 /0"
EXACTLY WHAT I WANTED.

but i get an access violation point to "xutility"....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

韵柒 2024-11-14 11:26:25

mvinstr(x,y,str) 等“从窗口中的当前或指定位置获取字符(或宽字符),并将它们作为字符串返回 str (或wstr)。”

该函数实际上会修改字符串,因此您不能安全地转换 const ,特别是因为 c_str 指定您不应修改返回的字符串。

您需要遵循以下内容:

const MAX = 100;
char buf[MAX];
mvinnstr(x, y, buf, MAX);
...error checking...
string s = buf;

请注意,我避免使用 mvinstr 而是使用 mvinnstr 以避免潜在的缓冲区溢出。

mvinstr(x,y,str) and others "take characters (or wide characters) from the current or specified position in the window, and return them as a string in str (or wstr)."

The function will actually modify the string, so you cannot safely cast the const away, especially since c_str specifies that you should not modify the returned string.

You need something along the lines of:

const MAX = 100;
char buf[MAX];
mvinnstr(x, y, buf, MAX);
...error checking...
string s = buf;

Note that I avoided mvinstr in favour of mvinnstr to avoid the potential for buffer overflows.

雪落纷纷 2024-11-14 11:26:25

不过

char* buffer = &str[0];
int fetched_len = mvinnstr(time_loc_y, time_loc_x, buffer, str.size());
str.resize(fetched_len);

,一般来说,您应该创建一个可写缓冲区,而不是从拥有它的指针中删除 const 。例如

vector<char> charvec(MAX_LENGTH);
str = string(&charvec[0], mvinnstr(time_loc_y, time_loc_x, &charvec[0], charvec.size());

How about

char* buffer = &str[0];
int fetched_len = mvinnstr(time_loc_y, time_loc_x, buffer, str.size());
str.resize(fetched_len);

In general, though, you should make a writable buffer instead of removing const from a pointer that has it. e.g.

vector<char> charvec(MAX_LENGTH);
str = string(&charvec[0], mvinnstr(time_loc_y, time_loc_x, &charvec[0], charvec.size());
素食主义者 2024-11-14 11:26:25

小心 - 如果使用 was-const 数据的代码尝试修改它,任何事情都可能发生。

简而言之:

const std::string str = "...";
char *caution = const_cast<char *>(str.c_str());

但是,鉴于您遇到了未处理的异常,您可能需要在调用 mvinstr() 之前制作常量字符串的可修改副本。或许:

const std::string str = "...";
char *caution = new char[str.length()+1];
str.copy(caution, str.length()+1);
...call to mvinstr()...
delete[] caution;

Cautiously - if the code that uses the was-const data tries to modify it, anything can happen.

In short:

const std::string str = "...";
char *caution = const_cast<char *>(str.c_str());

However, given that you are getting unhandled exceptions, you probably need to make a modifiable copy of the constant string before calling mvinstr(). Maybe:

const std::string str = "...";
char *caution = new char[str.length()+1];
str.copy(caution, str.length()+1);
...call to mvinstr()...
delete[] caution;
预谋 2024-11-14 11:26:25

由于mvinstr实际上是将数据存储到char*指向的数组中,因此您不能在那里使用string。您需要分配一个字符数组,将其传递给 mvinstr,然后根据需要将字符传输到 string

如果您使用的函数可以用 const char * 声明(即它实际上不会修改数组),那么您可以使用 const_cast删除const

const_cast<char *>(str.c_str());

但这不是你在这里做的。如果您尝试过,const_cast 可能会起作用,但这只是偶然,而不是因为它应该起作用,并且新的编译器或库版本可能随时会破坏它。

Since mvinstr is actually storing data into the array pointed at by the char*, you can't use a string there. You need to allocate an array of char, pass that to mvinstr, and then transfer the characters to a string if you want.

If you were using a function that could have been declared with a const char * (i.e. it doesn't actually modify the array), then you could use const_cast<> to remove the const.

const_cast<char *>(str.c_str());

But that's not what you're doing here. const_cast might work if you tried it, but it would be by accident, not because it's supposed to work, and a new compiler or library version could break it at any time.

韬韬不绝 2024-11-14 11:26:25

尝试如下操作,然后在需要 char* 的地方使用 buffer。正如 Ben 提到的,您需要非常小心地保持缓冲区大于字符串加上空终止符。

const int BUFFER_SIZE = 255;

string str ("Your string");
char buffer[BUFFER_SIZE];
if (str.length() < BUFFER_SIZE)
{
    size_t copy_length;
    copy_length=str.copy(buffer,str.length(),0);
    buffer[copy_length]='\0';
}

Try something like the following, then use buffer wherever you need a char*. As Ben mentioned, you need to be very careful to keep the buffer larger than the string plus null terminator.

const int BUFFER_SIZE = 255;

string str ("Your string");
char buffer[BUFFER_SIZE];
if (str.length() < BUFFER_SIZE)
{
    size_t copy_length;
    copy_length=str.copy(buffer,str.length(),0);
    buffer[copy_length]='\0';
}
少年亿悲伤 2024-11-14 11:26:25

可以使用 const_cast 删除 const,有时对于使用用 C 编写且不使用 const 的遗留接口是必要的。在这种情况下,您可以执行以下操作:

char* ptr = const_cast<char*> (str.c_str());

但是,从 c_str():

返回的数组指向一个内部位置,该位置具有该字符序列及其终止空字符所需的存储空间,但该数组中的值不应在程序中修改,并且只能保持不变,直到接下来调用字符串对象的非常量成员函数。

这意味着您有责任确保 ptr 用于修改字符串,并且您必须处理 的生命周期ptr 适当地。即,在 str 超出范围后,或者在 str 上调用任何非常量方法后,您不能继续使用 ptr。如果你这样做,你就会进入未定义的行为,并且可能会崩溃。

如果您正在寻找一种与采用 char* 的遗留接口交互的安全方法,您可以制作自己的可写副本:

char* ptr = new char[ str.size() + 1 ];
strcpy(ptr, str.c_str());
ptr[str.size()] = '\0';
// ... use ptr as much as you want...
delete [] ptr;

Removing const can be done with const_cast, and is sometimes necessary for using legacy interfaces that were written in C and don't use const. In such cases, you can do:

char* ptr = const_cast<char*> (str.c_str());

However, from the cplusplus reference page on c_str():

The returned array points to an internal location with the required storage space for this sequence of characters plus its terminating null-character, but the values in this array should not be modified in the program and are only granted to remain unchanged until the next call to a non-constant member function of the string object.

This means that it is your responsibility to ensure that ptr is not used to modify the string, and you must handle the lifetime of ptr appropriately. I.e., you cannot continue to use ptr after str is out of scope, or after you call any non-const methods on str. If you do that, you go into Undefined Behavior, and will likely crash.

If you are looking for a safe way to interact with a legacy interface that takes char*, you can make your own writable copy:

char* ptr = new char[ str.size() + 1 ];
strcpy(ptr, str.c_str());
ptr[str.size()] = '\0';
// ... use ptr as much as you want...
delete [] ptr;
望笑 2024-11-14 11:26:25

if (string.empty()) foo(const_cast(string.c_str());

删除 const 的更好但仍然邪恶的方法是 const_cast(const_string); (最好通过 grep/search 查找)

您遇到过 Witch 异常吗?
您只是读取 char* 还是更改值?如果你改变了,你应该重新设计你的代码。

const char* test = string.c_str();
不创建字符串的深层副本,仅创建指向 string.data() 的内部数据表示形式的指针。

=> (建议)找一本 C++ 书籍,在那里你可以更深入地了解 C++。或者类似 C++ 的东西。

if (string.empty()) foo(const_cast<char*>(string.c_str());

a better but still evil way to remove const is const_cast(const_string); (its better to find via grep/search)

Witch exception did you encountered?
Do u just read the char* or do you change the values? if you change, you should redesign your code.

const char* test = string.c_str();
Does not create a deep copy of string, only a pointer to the internal data representation of string.data().

=> (a suggestion) find a C++ book where you can get a more in deep view of c++. Or something like to C++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文