DWORD disk_serialINT[MAX_PATH + 1];
GetVolumeInformationA(NULL, NULL, NULL, disk_serialINT, NULL, NULL, NULL, NULL);
char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);
std::string HDDserial = disk_serialANSI;
这是我得到hdd序列号的代码片段,但问题是每次程序执行时值都不同。有人可以解释一下吗?
解决:
DWORD disk_serialINT;
GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL, NULL, NULL, NULL);
std::string HDDserial = std::to_string(disk_serialINT);
感谢。
答案 0 :(得分:7)
这两行会给你undefined behavior:
char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);
您声明了一个指针变量,但实际上并没有指向任何地方。未初始化的局部变量具有不确定的值(实际上它看起来是随机的),并且通过使用该未初始化的指针,您不知道 {/ 1}}调用将写入。
由于您使用C ++编程,因此有几种解决方案。
过时的方法是使sprintf
成为一个字符数组,大小足以容纳数字(包括字符串终结符)。另一种方法是为指针手动分配内存,然后在完成后再次释放该内存。
使用std::ostringstream
格式化数据并获得disk_serialANSI
。
使用std::to_string
直接转换为字符串。
答案 1 :(得分:3)
除了Joachim所说的,你没有正确传递序列号。您应该将指针传递给单个值。
DWORD disk_serialINT;
GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL, NULL, NULL, NULL);
在您的代码中,您在此处所做的事情更加复杂:
sprintf(disk_serialANSI, "%d", disk_serialINT);
忽略Joachim的答案涵盖的未初始化变量disk_serialANSI
,您将传递指向"%d"
格式字符串的指针。将disk_serialINT
更改为单个值后,事情会更好。但是,您将无符号值传递给单个格式字符串。
现在是时候放弃这些粗糙的C格式化函数,并使用C ++标准库在积分值和文本之间进行转换。
最后一点要强调的是,您必须检查对Win32 API的调用的返回值。你不知道函数调用是否成功。你不能认为它确实如此。这些都包含在文档中:https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993.aspx
该程序打印包含当前目录的卷的序列号:
#include <Windows.h>
#include <iostream>
int main()
{
DWORD disk_serialINT;
if (!GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL,
NULL, NULL, NULL))
{
std::cout << "Failed: " << GetLastError() << std::endl;
return 1;
}
std::cout << "Current directory volume serial numnber: " << std::hex
<< disk_serialINT << std::endl;
return 0;
}
答案 2 :(得分:0)
万一有人来看看这段代码,这里的解决方案就是我的看法:
问题1
DWORD disk_serialINT[MAX_PATH + 1];
DWORD
值的数组时就声明它。MAX_PATH
宏(并向其添加1)而不了解其用途。INT
类型为 unsigned 时命名变量DWORD
)。disk_serial
实际上是卷序列号时对其进行命名)。问题2
GetVolumeInformationA(NULL, NULL, NULL, disk_serialINT, NULL, NULL, NULL, NULL);
disk_serialINT
变量的地址)。问题3
char* disk_serialANSI;
问题4
sprintf(disk_serialANSI, "%d", disk_serialINT);
disk_serialANSI
。char
数组,或者保留指针但分配内存,然后再释放它)。%08lX
)。sprintf
。问题5
std::string HDDserial = disk_serialANSI;
换句话说,所有典型的初学者程序员错误。希望他们在此期间能学到更多,而不仅仅是在Stack Overflow上找到问题的答案。
上面已经有一个由David Heffeman提供的C ++解决方案,因此为了回答完整起见,这里是等效的C解决方案:
#include <stdio.h>
#include <windows.h>
int main()
{
const int VolumeSerialLength = 9; // 8 hex digits + zero termination
char VolumeSerial[VolumeSerialLength] = { 0 };
DWORD VolumeSerialNumber;
if (GetVolumeInformationA(NULL, NULL, NULL, &VolumeSerialNumber, NULL, NULL, NULL, NULL) {
sprintf_s(VolumeSerial, VolumeSerialLength, "%08lX", VolumeSerialNumber);
printf("Volume serial number: %8.8s.\n", VolumeSerial);
return 0;
} else {
printf("GetVolumeInformationA() error: %08lX\n", GetLastError());
return 1;
}
}