我试图列出我的PC的逻辑驱动器,并将结果添加到向量中,但是却出现了这个奇怪的result = ;;;
。
我在这里想念什么?
std::vector<std::string> directory::getLogicalDrives() {
DWORD mydrives = 100;
char lpBuffer[100];
DWORD drives = GetLogicalDriveStrings(mydrives, lpBuffer);
std::vector<std::string> driveList;
for (int i = 0; i < 100; i++) {
std::string drive(3, '%c' + lpBuffer[0]); // Missing something?
driveList.push_back(drive);
}
return driveList;
}
最佳答案
DWORD mydrives = 100;
char lpBuffer[100];
100个字符不足。从技术上讲,一台计算机最多可以包含26个驱动器号(实际上,没有人一次拥有那么多的驱动器号,但是您仍然应该为此做好准备)。一个100个字符的缓冲区有足够的空间来容纳最多24个驱动器号字符串(
4 * 24 + 1 = 97
,4 * 25 + 1 = 101
)。您的缓冲区中至少需要有105个字符的空间,才能接收26个驱动器号字符串(4 * 26 + 1 = 105
)。std::string drive(3, '%c' + lpBuffer[0]); // Missing something?
此行不执行您认为的操作。您正在考虑使用C样式的
sprint()
函数。您不能像这样使用std::string
格式化字符串。该行甚至不应编译,或应带有警告。此外,您甚至都无法正确遍历输出字符串。
GetLogicalDriveStrings()
以<drive>:\<nul>
格式返回双终止字符串列表,其中<drive>
在列表末尾为<nul>
。例如,如果返回驱动器A,B和C,则缓冲区的内容将如下所示:lpBuffer[ 0] = 'A';
lpBuffer[ 1] = ':';
lpBuffer[ 2] = '\\';
lpBuffer[ 3] = '\0';
lpBuffer[ 4] = 'B';
lpBuffer[ 5] = ':';
lpBuffer[ 6] = '\\';
lpBuffer[ 7] = '\0';
lpBuffer[ 8] = 'C';
lpBuffer[ 9] = ':';
lpBuffer[10] = '\\';
lpBuffer[11] = '\0';
lpBuffer[12] = '\0';
正确的方法是以4个字符为一组循环遍历缓冲区,直到到达最后一个空终止符为止(并且不要忘记进行错误检查!),例如:
DWORD drives = GetLogicalDriveStrings(mydrives, lpBuffer);
if ((drives > 0) && (drives <= mydrives)) {
char *pdrive = lpBuffer;
while (*pdrive) {
std::string drive(pdrive);
driveList.push_back(drive);
pdrive += 4;
}
}
或者:
DWORD drives = GetLogicalDriveStrings(mydrives, lpBuffer);
if ((drives > 0) && (drives <= mydrives)) {
for (int i = 0; i < drives; i += 4) {
std::string drive(&lpBuffer[i]);
driveList.push_back(drive);
}
}
话虽如此,请考虑使用
GetLogicalDrives()
代替,那么您完全不必担心为任何驱动器号字符串分配内存或循环访问它们:DWORD drives = GetLogicalDrives();
if (drives) {
char drive[] = "?:\\";
for (int i = 0; i < 26; i++) {
if (drives & (1 << i)) {
drive[0] = 'A' + i;
driveList.push_back(drive);
}
}
}
关于c++ - 将char转换为std::string不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42119306/