提问者:小点点

为什么把字符串传递给一个接受LPSTR的函数不起作用呢?


下面的代码给出了空字符串,长度=0,但在调试时,我可以看到childDisplayName的名称正确。

    CHAR fileSystemName[MAX_PATH + 1] = { 0 }; 
    DWORD serialNumber = 0; DWORD maxComponentLen = 0; 
    string childDisplayName = "";
    DWORD fileSystemFlags = 0; 
    if (GetVolumeInformationA("C:\\", // L"\\MyServer\MyShare\"
        (LPSTR)&childDisplayName, MAX_PATH+1,
        &serialNumber, &maxComponentLen,
        &fileSystemFlags, fileSystemName, sizeof(fileSystemName)) == true)
    {
        
        cout << childDisplayName << "length: "<<childDisplayName.length()<<endl;
    }


下面的代码可以正常工作。 我不明白为什么当我传递char数组时LPSTR工作,而当我传递字符串时LPSTR不工作。

    CHAR fileSystemName[MAX_PATH + 1] = { 0 }; 
    DWORD serialNumber = 0; DWORD maxComponentLen = 0; 
    CHAR childDisplayName[MAX_PATH + 1] = { 0 };
    DWORD fileSystemFlags = 0; 
    if (GetVolumeInformationA("C:\\", // L"\\MyServer\MyShare\"
        childDisplayName, MAX_PATH+1,
        &serialNumber, &maxComponentLen,
        &fileSystemFlags, fileSystemName, sizeof(fileSystemName)) == true)
    {
        
        cout << childDisplayName << "length: "<<strlen(childDisplayName)<<endl;
    }

共1个答案

匿名用户

string childDisplayName=“”;创建一个空的空字符串(大小为零,容量未指定)。 使用它作为数据缓冲区进行写入不太可能很好。

您可以这样做:string childDisplayName(MAX_PATH+1,'');创建一个具有适当空间分配的字符串。

其次,正如@Churill所写的那样,字符串的地址并不是其中字符的地址。 相反,使用ChildDisplayName.data()char*获取到可以写入的字符串的内部存储区-但确保不要在[data();data()+size()范围之外写入。

编辑:介绍std::string.data()的工作原理。

我做了一个小的示例程序:

#include<iostream>
#include<string>

void print(const std::string& s)
{
    std::cout << "String size: " << s.size() << '\n';
    std::cout << "String contents: >>" << s << "<<\n";
    std::cout << "String as c-string: >>" << s.c_str() << "<<\n";
    std::cout << '\n';
}

int main() {
    std::string bla = "";
    auto bladata = bla.data();
    for (int i = 0;i < 5;++i) {
        bladata[i] = '!';
    }
    print(bla);

    std::string bla2(10, '\0');
    auto bla2data = bla2.data();
    for (int i = 0;i < 5;++i) {
        bla2data[i] = '!';
    }
    print(bla2);
}

运行此输出时:

String size: 0
String contents: >><<
String as c-string: >>!!!!!╠╠╠╠╠╠╠╠╠╠╠<<

String size: 10
String contents: >>!!!!!     <<
String as c-string: >>!!!!!<<

这是怎么回事? 首先要注意的是,创建了一个空的std::string,其大小为零,容量未指定--在我的调试器中查看,我知道在我的系统上,未指定的容量为15,因此只要不超出这个值,就不会有任何东西崩溃。 但这显然不是您在真实代码中应该做的事情(这里的编写是严格的未定义行为)。

这意味着bla字符串的大小为0,并且包含一个15个字符的字符缓冲区,我将其中的前5个字符设置为“!”。 因此,当我尝试打印其size()或将其打印为std::string时,它与任何常规空字符串都是相同的。 但是,如果我使用.c_str()直接打印内部缓冲区,那么它将作为任何旧的char*打印,并且只打印内存中的任何内容,直到遇到空字符为止。

另一方面,bla2被初始化为包含10个空字符。 这意味着它的大小是10,它的容量至少是10(在我的例子中它碰巧也是15)。 这意味着在循环之后,它仍然报告大小为10,而不管我在缓冲区中放了多少个‘!’,当我将它打印为std::string时,它将打印它包含的所有10个字符; 5'\0和5'\0都有。 但是,当我将它打印为char*时,它会打印5‘!,然后一旦遇到空字符就会停止。