为什么获取网站源码时会出现特殊字符? C++

Why do I get special characters when getting the source code of a website? c++

我正在尝试获取巴拉克奥巴马维基百科页面的源代码并将其保存到文件中。

一切正常,直到我打开文件并在其中看到一些奇怪的字符:

如您所见,EOT1024出现在文件中,但它没有出现在网站的实际源代码中,我使用Google Chrome检查过。我想知道为什么会发生这种情况,以及如何阻止它发生。

我的代码:

#include <iostream>
#include <windows.h>
#include <wininet.h>
#include <fstream>
int main(){
    std::string textLink = "https://en.wikipedia.org/wiki/Barack_Obama";
    std::ofstream file;
    HINTERNET hInternet, hFile;
    char buf[1024];
    DWORD bytes_read;
    int finished = 0;
    bool e=false;
    std::string waste;

        file.open("data.txt",std::ios::out);
        hInternet = InternetOpenW(L"Whatever", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        if (hInternet == NULL) {
            printf("InternetOpen failed\n");
        }
        hFile = InternetOpenUrl(hInternet, textLink.c_str(), NULL, 0L, 0, 0);
        if (hFile == NULL) {
            printf("InternetOpenUrl failed\n");
        }
        while (!finished) {
            if (InternetReadFile(hFile, buf, sizeof(buf), &bytes_read)) {
                if (bytes_read > 0) {
                    file  << bytes_read << buf;
                }
                else {
                    finished = 1;
                }
            }
            else {
                printf("InternetReadFile failed\n");
                finished = 1;
            }
        }
        InternetCloseHandle(hInternet);
        InternetCloseHandle(hFile);
        file.close();
}

我在 Notepad++ 中查看的文本文件就在这里:

https://drive.google.com/open?id=1Ty-a1o29RWSQiO1zTLym6XH4dJvUjpTO

我不明白为什么我会在我写入的 data.txt 文件中得到这些字符。

注意: 偶尔,我什至没有看到 EOT1024,而是 EOT21EOT1016 和其他看似随机的字符。

您实际上是在将整数 bytes_read 写入文件:

file  << bytes_read << buf;

这是你的“1024”(在读取 1024 个字节的情况下)。

不要那样做。

此外,您似乎假设 buf 是 null-terminated。相反,流式传输 buf 的第一个 bytes_read;这就是为什么你有那个整数。

所以:

file.write(&buf[0], bytes_read);

咨询the documentation:

A normal read retrieves the specified dwNumberOfBytesToRead for each call to InternetReadFile until the end of the file is reached. To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.