鱼C论坛

 找回密码
 立即注册
查看: 890|回复: 11

[已解决]CopyMemory

[复制链接]
发表于 2023-8-3 13:38:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        
        TCHAR szname[50] = _T("物理");
        TCHAR szfriend[] =_T("化学数学");
        
        CopyMemory(szname+4, szfriend,8);   //复制内存数据
        /*
        参数1:PVOID Destination   要复制内存块的目的地址
        参数2:CONST VOID *Source   要复制内存块的源地址
        参数3:SIZE_T Length       指定要复制内存块的大小,单位为字节
        没有返回值
        
        */

        OutputDebugString(szname);


我的问题:OutputDebugString(szname)  只是输出物理,化学数学  没有复制进去  ?
最佳答案
2023-8-3 13:53:33
lm68140318 发表于 2023-8-3 13:46
TCHAR szname[50] = _T("物理");     长度应该是50个字符   ?

对不起,我在之前的回答中可能没有清楚地解释。TCHAR szname[50] = _T("物理"); 这行代码中,虽然你为 szname 分配了 50 个字符的空间,但实际上你只使用了其中的两个字符来存储 "物理",并且还有一个字符用于存储字符串的结束符 '\0'。所以,实际上你只使用了 3 个字符的空间。

当你执行 CopyMemory(szname + 4, szfriend, 8); 这行代码时,你试图从 szname 的第五个字符位置开始复制 "化学数学"。由于 TCHAR 是一个宽字符类型(在 Unicode 编译选项下),每个字符占用两个字节,所以你实际上复制了 4 个字符(8 个字节)到 szname 的第五个字符位置。


这就是为什么你没有看到 "化学数学" 被复制到 szname 中的原因。你应该将 CopyMemory 的第三个参数(复制的字节数)更改为 szfriend 的实际字节数,而不是固定的 8。你可以使用 sizeof(szfriend) 来获取 szfriend 的实际字节数。


所以,你的代码应该修改为:

TCHAR szname[50] = _T("物理");
TCHAR szfriend[] = _T("化学数学");


CopyMemory(szname + 2, szfriend, sizeof(szfriend));  // 复制整个 szfriend 数组的内容
OutputDebugString(szname);


这样,你就能够正确地将 "化学数学" 复制到 szname 数组中,并且能够正确地输出整个字符串 "物理化学数学"。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 13:38:15 | 显示全部楼层
【关于 CopyMemory 的问题】

根据你提供的代码,CopyMemory 函数的使用似乎有一点小问题。我注意到你想将字符串 "化学数学" 复制到字符串 "物理" 的后面。

问题出在这里:CopyMemory(szname+4, szfriend,8);

如果你希望将 "化学数学" 复制到 "物理" 的后面,你应该将 CopyMemory 的第一个参数设置为 szname + 6,而不是 szname + 4。因为字符串 "物理" 的长度是 6 个字符(包括结尾的空字符 '\0'),所以你需要将源地址设置为 szname + 6

修正后的代码如下:
TCHAR szname[50] = _T("物理");TCHAR szfriend[] = _T("化学数学");CopyMemory(szname+6, szfriend, 8); // 复制内存数据OutputDebugString(szname);
这样,复制后的结果应该是 "物理化学数学"。

请根据上述修改尝试一下。如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 13:38:16 | 显示全部楼层
【关于 CopyMemory 函数的问题】

根据你提供的代码,使用 CopyMemory 函数复制内存块的操作似乎没有达到预期效果。我注意到在复制内存块时,你设置了目的地址为 szname+4,源地址为 szfriend,并指定要复制的大小为 8 字节。然而,你想要的结果是将 "化学数学" 复制到 szname 中,但实际上没有实现。

原因是你在复制内存块之前并没有为 szname 分配足够的空间来容纳 "化学数学" 这个字符串。在你的代码中,szname 数组被初始化为长度为 50 的字符数组,并且初始值为 "物理"。由于 "物理" 占据了 6 个字符,因此在 szname 数组中只有剩余的 44 个字符可用来容纳复制的字符串。

因此,为了使复制操作成功,你需要确保目标地址足够大以容纳要复制的内容。修改代码如下所示:
TCHAR szname[50] = _T("物理");TCHAR szfriend[] = _T("化学数学");CopyMemory(szname + 6, szfriend, sizeof(szfriend)); // 修改目标地址为 szname+6OutputDebugString(szname);
这样修改后,"化学数学" 将会复制到 szname 的正确位置,然后通过 OutputDebugString 输出时,你将看到正确的结果。

希望能解答你的问题。如果还有其他疑问,请随时提出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 13:38:17 | 显示全部楼层
CopyMemory  函数的使用似乎出现了一些问题。让我解释一下为什么你没有得到预期的输出。

首先,让我们看一下你的代码:
TCHAR szname[50] = _T("物理");
TCHAR szfriend[] = _T("化学数学");

CopyMemory(szname + 4, szfriend, 8);
OutputDebugString(szname);

你的  szname  数组的初始内容是  "物理" ,长度为 6 个字符(包括结尾的 null 终止符)。然后,你尝试使用  CopyMemory  将  szfriend  数组的内容复制到  szname  数组中的  szname + 4  位置,复制长度为 8 个字节。

问题在于, szname  数组的总长度是 50 个字符,但是你只在数组的前 6 个位置写入了数据。所以,当你尝试复制  szfriend  的内容时,它会覆盖  szname  数组的一部分,但仍然没有足够的空间来存储完整的  "化学数学" 。因此,你只会看到  "物理"  被输出。

要解决这个问题,你需要确保目标数组有足够的空间来容纳要复制的数据。你可以考虑增大  szname  数组的大小,以确保能够容纳  "物理化学数学"  这个字符串。例如:
TCHAR szname[50] = _T("物理");
TCHAR szfriend[] = _T("化学数学");

CopyMemory(szname + 4, szfriend, sizeof(szfriend));  // 复制整个 szfriend 数组的内容
OutputDebugString(szname);

这样,你就能够正确地将  "化学数学"  复制到  szname  数组中,并且能够正确地输出整个字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 13:41:28 | 显示全部楼层
学习编程中的Ben 发表于 2023-8-3 13:38
【关于 CopyMemory 的问题】

根据你提供的代码,CopyMemory 函数的使用似乎有一点小问题。我注意到你想将 ...

应该把"\0"覆盖掉啊   ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 13:44:49 | 显示全部楼层
Mike_python小 发表于 2023-8-3 13:38
【关于 CopyMemory 函数的问题】

根据你提供的代码,使用 CopyMemory 函数复制内存块的操作似乎没有达到预 ...

结果不对  ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 13:46:40 | 显示全部楼层
本帖最后由 Mike_python小 于 2023-8-3 10:50 编辑

TCHAR szname[50] = _T("物理");
TCHAR szfriend[] = _T("化学数学");

CopyMemory(szname + _tcslen(szname), szfriend, (_tcslen(szfriend) + 1) * sizeof(TCHAR));

或者
#include <Windows.h>

int main()
{
    TCHAR szname[50] = _T("物理");
    TCHAR szfriend[] = _T("化学数学");

    size_t friendLength = (_countof(szfriend) + 1) * sizeof(TCHAR); // 增加 sizeof(TCHAR)
    size_t destinationSize = (_countof(szname) - 4) * sizeof(TCHAR);

    if (destinationSize >= friendLength)
    {
        CopyMemory(szname + 4, szfriend, friendLength);
    }

    OutputDebugString(szname);

    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 13:46:58 | 显示全部楼层
isdkz 发表于 2023-8-3 13:38
CopyMemory  函数的使用似乎出现了一些问题。让我解释一下为什么你没有得到预期的输出。

首先,让我们 ...

TCHAR szname[50] = _T("物理");     长度应该是50个字符   ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 13:49:23 | 显示全部楼层
如果你想要将\0(字符串结尾的空字符)一并复制到目标地址中,确保在使用 CopyMemory 函数时包含\0。在示例代码中,可以将 friendLength 的大小增加 sizeof(TCHAR),以便复制\0:
#include <Windows.h>

int main()
{
    TCHAR szname[50] = _T("物理");
    TCHAR szfriend[] = _T("化学数学");

    size_t friendLength = (_countof(szfriend) + 1) * sizeof(TCHAR); // 增加 sizeof(TCHAR)
    size_t destinationSize = (_countof(szname) - 4) * sizeof(TCHAR);

    if (destinationSize >= friendLength)
    {
        CopyMemory(szname + 4, szfriend, friendLength);
    }

    OutputDebugString(szname);

    return 0;
}
通过增加 sizeof(TCHAR),我们将 friendLength 设置为适合复制的字节数。然后在 CopyMemory 函数中,我们指定复制 friendLength 个字节到目标地址,并包括 \0 在内。

执行修改后的代码后,OutputDebugString 应该会输出 "物理化学数学",表示复制操作已成功,并且 \0 会覆盖原来的字符。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 13:53:33 | 显示全部楼层    本楼为最佳答案   
lm68140318 发表于 2023-8-3 13:46
TCHAR szname[50] = _T("物理");     长度应该是50个字符   ?

对不起,我在之前的回答中可能没有清楚地解释。TCHAR szname[50] = _T("物理"); 这行代码中,虽然你为 szname 分配了 50 个字符的空间,但实际上你只使用了其中的两个字符来存储 "物理",并且还有一个字符用于存储字符串的结束符 '\0'。所以,实际上你只使用了 3 个字符的空间。

当你执行 CopyMemory(szname + 4, szfriend, 8); 这行代码时,你试图从 szname 的第五个字符位置开始复制 "化学数学"。由于 TCHAR 是一个宽字符类型(在 Unicode 编译选项下),每个字符占用两个字节,所以你实际上复制了 4 个字符(8 个字节)到 szname 的第五个字符位置。


这就是为什么你没有看到 "化学数学" 被复制到 szname 中的原因。你应该将 CopyMemory 的第三个参数(复制的字节数)更改为 szfriend 的实际字节数,而不是固定的 8。你可以使用 sizeof(szfriend) 来获取 szfriend 的实际字节数。


所以,你的代码应该修改为:

TCHAR szname[50] = _T("物理");
TCHAR szfriend[] = _T("化学数学");


CopyMemory(szname + 2, szfriend, sizeof(szfriend));  // 复制整个 szfriend 数组的内容
OutputDebugString(szname);


这样,你就能够正确地将 "化学数学" 复制到 szname 数组中,并且能够正确地输出整个字符串 "物理化学数学"。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-3 14:00:19 | 显示全部楼层
isdkz 发表于 2023-8-3 13:53
对不起,我在之前的回答中可能没有清楚地解释。TCHAR szname[50] = _T("物理"); 这行代码中,虽然你为 sz ...

两个汉字应该是4字节 ?为何+2   ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-3 14:12:00 | 显示全部楼层
lm68140318 发表于 2023-8-3 14:00
两个汉字应该是4字节 ?为何+2   ?

因为 TCHAR 是宽字符类型,一个字符可以表示一个中文字符,在 gbk 编码中,一个 TCHAR 可以表示 2 个字节
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 18:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表