我需要{(1)}(有效地)从(编辑:MFC)CString对象到C字符串变量。众所周知,strncpy()
有时会失败(取决于源长度** EDIT 和调用中指定的长度)来正确终止dest C字符串。为了避免这种恶意,我想将NUL字符存储在CString源对象中,然后存储到那个人的strncpy()
或strcpy()
。
这是一种合理的方式吗?如果是这样,我必须在CString对象中操作什么?如果没有,那么什么是保证正确终止目的地C字符串的替代方案?
答案 0 :(得分:1)
CSimpleStringT::GetString给出一个指向以null结尾的字符串的指针。将此作为strncpy
的来源。由于这是C ++,因此在与旧版API交互时只应使用C风格的字符串。请改用std::string
。
答案 1 :(得分:1)
我希望他们从使用它们时不会改变:那是多年前的事情:)
他们使用了一个有趣的'技巧'来处理refcount和非常快速有效的自动转换为char *:即指针指向LPCSTR,但是保留了一些返回字节以保持实现状态。
因此,结构可以使用与旧的Windows API(LPCSTR没有开销)。我当时发现这个想法很有意思!
当然关键是分配器的可用性:它们只是在mallocing / freeing时偏移指针。
我记得有一个缓冲区请求(例如)修改可用数据:GetBuffer(0),然后是ReleaseBuffer()。
HTH
答案 2 :(得分:1)
strncpy()
仅“失败”以空终止目标字符串。您可以通过将其最后一个字符设置为null来确保目标为空终止。例如:
#define DEST_STR_LEN 10
char dest_str[DEST_STR_LEN + 1]; // +1 for the null
strncpy(dest_str, src_str, DEST_STR_LEN);
dest_str[DEST_STR_LEN] = '\0';
如果src_str
长度超过DEST_STR_LEN
个字符,则dest_str
将是一个正确终止的DEST_STR_LEN
字符字符串。如果src_str
比strncpy()
短,dest_str
会在{{1}}内的某处放置一个空终止符,因此最后的空值无关紧要且无害。
答案 3 :(得分:1)
其中一种替代方法是首先将字符串置零,然后从CString中转换或memcpy。
答案 4 :(得分:1)
如果您未在启用_UNICODE
的情况下进行编译,那么您可以非常轻松地从const char *
获得CString
。只需将其投放到LPCTSTR
:
CString myString("stuff");
const char *byteString = (LPCTSTR)myString;
保证以NULL结尾。
如果 使用_UNICODE
构建,则CString
是UTF-16编码的字符串。你无法直接用它做任何事情。
如果您确实需要从CString
复制数据,这非常简单,即使使用C风格的代码也是如此。只需确保分配足够的内存并复制正确的长度:
CString myString("stuff");
char *outString = (char*)malloc(myString.Length() + 1);
strncpy(outString, (LPCTSTR)myString, myString.Length());
答案 5 :(得分:1)
CString以NULL结尾,只要你的文本正确(里面没有NULL字符),那么复制应该是安全的。你可以写:
char szStr[256];
strncpy(szStr, (LPCSTR) String, 3);
szStr[3]='\0'; /// b-cos no null-character is implicitly appended to the end of destination
如果你在CString对象中存储null,你可能会给自己带来更多问题,CString会在内部存储它的长度。
答案 6 :(得分:0)
另一种替代解决方案宁愿涉及来自CPU或编译器的支持,因为它是更好的方法 - 只需确保在“安全”模式下复制内存时,在每次原子操作之后的任何时间都会在最后添加零,所以当整个循环失败时,目标字符串仍将被终止,而不需要在复制之前将其完全归零。 也可以支持快速零 - 只需标记零点区域的开始和停止,它就会立即在RAM中清除,这会使事情变得更容易。