C++ 将字符数组连接在一起

C++ 将字符数组连接在一起,c++,concatenation,strcpy,strncpy,C++,Concatenation,Strcpy,Strncpy,这是几年前我认为微不足道的事情。。。我已经涉足C或C++,我现在有一个问题,现在是偏头痛。 我收到以下代码的错误: CompressFile::CompressFile(wchar_t *WorkingDirectory, wchar_t *File) { int bzipError = BZ_OK; wprintf(L"Attempting to compress %s%s\n", WorkingDirectory, File); wchar_t FileRawIn

这是几年前我认为微不足道的事情。。。我已经涉足C或C++,我现在有一个问题,现在是偏头痛。 我收到以下代码的错误:

CompressFile::CompressFile(wchar_t *WorkingDirectory, wchar_t *File)
{
    int bzipError = BZ_OK;

    wprintf(L"Attempting to compress %s%s\n", WorkingDirectory, File);

    wchar_t FileRawInput[MAX_PATH];
    wcsncpy(FileRawInput, WorkingDirectory, sizeof(FileRawInput));
    wcsncat(FileRawInput, File, sizeof(FileRawInput));

    wchar_t bzipCompressedOutput[MAX_PATH];
    wcsncpy(bzipCompressedOutput, FileRawInput, sizeof(bzipCompressedOutput));
    wcscat(bzipCompressedOutput, L".bz2"); 

    wprintf(L"Output of string bzip: %s\n", bzipCompressedOutput);
    wprintf(L"Output of string raw: %s\n", FileRawInput);
}
我在第8行收到以下错误:

Unhandled exception at 0x64F4C6D1 in ias-agent.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003).
我已经尽量避免使用
string
类,我希望暂时保持这种方式。我想做的就是,为<代码> RWFILIMPUTION/CODE添加两个字符串,然后添加代码< > RWFILIVENTION/COD> >代码> BZIPCACHECTORIONS < /COD>,最后,连接<代码> BZ2<代码>结束代码> BZIPCACHECTORIONS输出/<代码>

< P>:“C++编程语言”:

与C样式字符串相比,更喜欢
字符串

这只是一个建议,但我鼓励你遵循它


但是你真正的问题是你在消耗内存,在你的
FileRawInput
中没有
sizeof(FileRawInput)
wchar\u t
同样地,在
bzipCompressedOutput
数组中也没有
sizeof(bzipCompressedOutput)
同样,在这两个数组中都有
MAX\u PATH
wchar。问题是
sizeof
将告诉您数组中的字节数,但如果每个元素大于1字节,则说明您错误地告诉了
wcsncpy
wscncat
您的字符数。一个
wchar\u t
通常是2个字节:这意味着您正在有效地调用
wcsncpy(FileRawInput,WorkingDirectory,200)
。在已分配的内存之外跺100
wchar\u t
s。纠正此错误将消除您的错误

但是为了打印宽字符串,您需要正确地使用
%ls
修饰符来
wprintf

最终,您的代码应该如下所示:

wprintf(L"Attempting to compress %ls%ls\n", WorkingDirectory, File);

wchar_t FileRawInput[MAX_PATH];
wcsncpy(FileRawInput, WorkingDirectory, MAX_PATH);
wcsncat(FileRawInput, File, MAX_PATH);

wchar_t bzipCompressedOutput[MAX_PATH];
wcsncpy(bzipCompressedOutput, FileRawInput, MAX_PATH);
wcscat(bzipCompressedOutput, L".bz2");

wprintf(L"Output of string bzip: %ls\n", bzipCompressedOutput);
wprintf(L"Output of string raw: %ls\n", FileRawInput);

编辑:

OP已经默认了Bjarne Stroustrup的建议,并转到了
wstring
:但是对于仍然坚持使用这些C风格函数的任何人来说,
MAX\u PATH
必须足够大,以容纳
wsclen(工作目录)+wsclen(文件)+wsclen(L.bz2”)
加上
L'\0'
字符,因此,在该函数上放置if语句可能会很有用,或者:

assert(MAX_PATH > wsclen(WorkingDirectory) + wsclen(File) + wsclen(L".bz2"))

为什么要避免使用
std::wstring
?如果需要可修改的
wchar
缓冲区,请使用
std::vector
,否则,请使用
std::wstring
。这种C风格的字符串业务是在浪费你宝贵的时间。(一如既往,除非你能证明一个显著的优势,但在这种情况下似乎不太可能。)最后的参数<代码> WCSncPy < /C>和 WCSnCAT应该是字符的数量(即<>代码> W查尔特特< /Cords>),而不是在<代码> char < /C++ >中所测量的大小。比较发布到的内容。没有缓冲区溢出,没有摆弄
sizeof
来搞乱事情,并且保证能正常工作。有几个问题:首先,您调用
wcsncpy
并传递
sizeof(…)
,这会给您缓冲区中的字节数,这是错误的:函数获取缓冲区中的字符数,所以您需要
sizeof(x)/sizeof(x[0])
。第二,我觉得这有点像堆栈损坏,所以我会问一个明显的问题:您是否100%确定
WorkingDirectory
File
适合
MAX\u PATH
字符?如果它们不这样做,
wcsncpy
将不为null并终止
FileRawInput
,这可能会导致“奇怪的”崩溃。你应该避免像瘟疫一样的
wcsncpy
。我确实解决了我的问题。。。但我接受了上面的建议,转而使用字符串。见鬼,如果那个人自己告诉你使用字符串,那么你可能应该这样做。谢谢你抽出时间
sizeof(数组)
sizeof(*)
不同。但是,它是以字节而不是单位度量的。@rici我希望
*
中有
FileRawInput
bzipCompressedOutput
,但我看不清楚。我已经删除了我的懒惰。酷,+1。您忽略了一个事实,即wcsn{cpy,cat}中的n度量的是源,而不是目标,并且目标需要比NUL长一个字符。我想您可能知道,Microsoft的
wprintf
中的
“%s”
确实需要常量wchar*
,这与标准C不同,标准C要求常量char*`指向多字节字符串。因此符合标准的标准库需要
“%ls”
,因此为了便于移植,但在windows上
“%s”
很不幸会按照OP的要求进行操作。@我同意,这就是我们使用
wstring
的原因,对吗?为了完成,我在答案后面加上了这张支票的必要性。