使WCHAR null终止

时间:2009-11-27 00:43:57

标签: visual-c++

我有这个

WCHAR fileName [1];

作为函数的返回值(它是一个sys 32函数,所以我无法更改返回的类型)。我需要让fileName为null终止,所以我试图将'\ 0'附加到它,但似乎没有任何效果。

一旦我得到一个空终止的WCHAR,我需要将它传递给另一个sys 32函数,所以我需要它保持为WCHAR。

有人可以给我任何建议吗?

=============================================== =

非常感谢你的帮助。看起来我的问题不仅仅是缺少一个空终止的字符串。

//这有效:

WCHAR szPath1[50] = L"\\Invalid2.txt.txt";
    dwResult = FbwfCommitFile(szDrive, pPath1); //Successful

//这不是:

std::wstring l_fn(L"\\");  
    //Because Cache_detail->fileName is \Invalid2.txt.txt and I need two
l_fn.append(Cache_detail->fileName);
l_fn += L""; //To ensure null terminated
fprintf(output, "l_fn.c_str: %ls\n", l_fn.c_str()); //Prints "\\Invalid2.txt.txt"

    iCommitErr = FbwfCommitFile(L"C:", (WCHAR*)l_fn.c_str()); //Unsuccessful

//当我对这两者进行比较时,他们是不平等的。

int iCompareResult = l_fn.compare(pPath1);  // returns -1

所以我需要弄清楚这两者最终是如何不同的。

非常感谢!

4 个答案:

答案 0 :(得分:4)

由于您在评论中提到了fbwffindfirst / fbwffindnext,因此您谈论的是FbwfCacheDetail中返回的文件名。因此,从fileNameLength字段可以知道fileName的长度(以字节为单位)。 WCHAR中fileName的长度是fileNameLength / sizeof(WCHAR)。所以简单的答案就是你可以设置

fileName[fileNameLength/sizeof(WCHAR)+1] = L'\0'

现在这是重要你需要确保你为cacheDetail参数发送到fbwffindfirst / fbwffindnext的缓冲区的sizeof(WCHAR)字节大于你需要的,上面的代码片段可能在外面运行你的数组的边界。所以对于fbwffindfirst / fbwffindnext的size参数传递缓冲区大小 - sizeof(WCHAR)。

例如:

// *** Caution: This example has no error checking, nor has it been compiled ***
ULONG error;
ULONG size;
FbwfCacheDetail *cacheDetail;

// Make an intial call to find how big of a buffer we need
size = 0;
error = FbwfFindFirst(volume, NULL, &size);
if (error == ERROR_MORE_DATA) {
    // Allocate more than we need
    cacheDetail = (FbwfCacheDetail*)malloc(size + sizeof(WCHAR));
    // Don't tell this call about the bytes we allocated for the null
    error = FbwfFindFirstFile(volume, cacheDetail, &size);
    cacheDetail->fileName[cacheDetail->fileNameLength/sizeof(WCHAR)+1] = L"\0";

    // ... Use fileName as a null terminated string ...

    // Have to free what we allocate
    free(cacheDetail);
}

当然,您必须改变一下以适应您的代码(此外,您还必须调用fbwffindnext)

如果您对FbwfCacheDetail结构以WCHAR [1]字段结尾的原因感兴趣,请参阅此blog post。这是Windows API中非常常见的模式。

答案 1 :(得分:2)

使用L'\ 0',而不是'\ 0'。

答案 2 :(得分:0)

由于WCHAR的每个字符的大小都是16位,你或许应该将\0\0附加到它,但我不确定这是否有效。顺便说一句,WCHAR fileName[1];正在创建一个长度为1的WCHAR,也许你想要WCHAR fileName[1024];之类的东西。

答案 3 :(得分:0)

WCHAR fileName[1];是一个包含1个字符的数组,因此如果null终止,它将只包含空终止符L'\0'

您打算使用哪种API函数?

被修改

fileName中的FbwfCacheDetail成员只有1个字符,这是当数组长度未知且成员是结构中最后一个成员时使用的常用技术。您可能已经注意到,如果分配的缓冲区长度仅为sizeof (FbwfCacheDetail),则FbwfFindFirst将返回ERROR_NOT_ENOUGH_MEMORY

因此,如果我理解,你想做什么,使用fprintf输出非NULL终止的文件名。这可以按如下方式完成

fprintf (outputfile, L"%.*ls", cacheDetail.fileNameLength, cacheDetail.fileName);

这将仅打印fileNameLength的第一个fileName个字符。

另一种方法是将NULL终止符附加到fileName的末尾。首先,您需要确保缓冲区足够长,可以通过从传递给FbwfFindFirst的sizeof (WCHAR)参数中减去size来完成。因此,如果你分配一个1000字节的缓冲区,你将把998传递给FbwfFindFirst,保留缓冲区中的最后两个字节供你自己使用。然后添加NULL终止符并输出文件名使用

cacheDetail.fileName[cacheDetail.fileNameLength] = L'\0';
fprintf (outputfile, L"%ls", cacheDetail.fileName);