我写了一个简单的程序来从雅虎财务中获取股票价格.读取数据的循环提前截断(并且结束了网站上的数据显示的位置,而不是完整下载到excell文件的正确日期).所以我在循环中输入一个cout命令来尝试调试和瞧,它工作正常!
那么为什么使用cout函数会改变程序功能呢?有任何想法吗?下面是代码.(我发现了两个相关的帖子,但仍然无法弄明白,例如"可以以某种方式改变变量?"和"C++程序中的奇怪错误:删除打印输出中断程序")
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <windows.h>
#include <wininet.h>
using namespace std;
int main()
{
HINTERNET hOpen, hURL;
LPCWSTR NameProgram = L"Webreader"; // LPCWSTR == Long Pointer to Const Wide String
LPCWSTR Website;
char file[101];
int i;
string filename;
unsigned long read;
filename = "data.txt";
ofstream myFile(filename);
if (! myFile)
{
cout < "Error opening file\n";
}
if ( !(hOpen = InternetOpen(NameProgram, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 )))
{
cerr << "Error in opening internet" << endl;
return 0;
}
Website = L"http://ichart.finance.yahoo.com/table.csv?s=MSFT&a=00&b=1&c=2009&d=09&e=22&f=2010&g=d&ignore=.csv";
hURL = InternetOpenUrl( hOpen, Website, NULL, 0, 0, 0 ); //Need to open the URL
InternetReadFile(hURL, file, 100, &read);
file[read] = '\0';
myFile << file;
while (read == 100)
{
InternetReadFile(hURL, file, 100, &read);
file[read] = '\0';
myFile << file;
cout << file; //If I take this line out, the function terminates early.
}
myFile << file;
InternetCloseHandle(hURL);
myFile.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你所拥有的是一种"Heisenbug",当你试图找到它时它会消失.毫无疑问,问题仍然存在,你确实需要找到它.
你应该做的第一件事是检查返回代码InternetReadFile.
此外,您应该不认为一个成功的读操作将返回完整的100个字节,即使有更多的惊喜.该DOCO状态:
为了确保检索所有数据,应用程序必须继续调用该
InternetReadFile函数,直到函数返回TRUE并且lpdwNumberOfBytesRead参数等于零.:::
此外,转换后的行可能无法完全填充缓冲区,因此
InternetReadFile可以返回的数据lpBuffer少于请求的数据.
换句话说,我会补充:
BOOL rc;
Run Code Online (Sandbox Code Playgroud)
并改变你的两个:
InternetReadFile(hURL, file, 100, &read);
Run Code Online (Sandbox Code Playgroud)
声明:
rc = InternetReadFile(hURL, file, 100, &read);
Run Code Online (Sandbox Code Playgroud)
然后你的循环变成:
while ((!rc) || (read > 0)) // I *think* that's right.
Run Code Online (Sandbox Code Playgroud)
做一些输出可能需要一点时间,在此期间数据可以从网络到达,准备好在下次调用时读取InternetReadFile.
我没有使用那种野兽,但如果它像其他读取函数一样工作,那么它不一定读取100个字节,它可能会读取更少的东西.
如果是这样,那么不要read == 100用作循环的延续条件.使用例如read > 0.但请检查文档,它应该告诉您期待什么.
根据函数的低级别,也可能是零字节读取并不意味着完成.可能需要检查返回值.例如,在继续之前做一点延迟.
干杯&hth.,