2

Yahoo Finance から株価を取得する簡単なプログラムを作成しました。データを読み取るループは早期に切り捨てられました (そして、Excel ファイルの正しい日付への完全なダウンロードとは対照的に、Web サイトからのデータが表示される場所について終了しました)。それで、ループに cout コマンドを入れてデバッグを試みたところ、正しく動作しました!

では、なぜ cout 関数を使用するとプログラム関数が変更されるのでしょうか? 何か案は?以下はコードです。(関連する 2 つの投稿を見つけましたが、まだわかりません。たとえば、「どうにかして変数を変更できますか?」と「C++ プログラムの奇妙なエラー: Printout Breaks プログラムの削除」など)。

#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;
}
4

2 に答える 2

7

あなたが持っているのは、見つけようとすると消えてしまう「ハイゼンバグ」です。間違いなく、問題はまだ残っており、それを見つける必要があります。

最初すべきことは、 のリターン コードをチェックすることですInternetReadFile

さらに、読み取りが成功すると、さらに 100 バイトが返されると想定しないでください。docoは次のように述べています。

すべてのデータが確実に取得されるようにするには、関数が戻り、パラメーターがゼロにInternetReadFileなるまで、アプリケーションで関数を呼び出し続ける必要があります。TRUElpdwNumberOfBytesRead

: : :

また、変換された行がバッファを完全に満たしていない可能性があるため、要求されたよりもInternetReadFile少ないデータで返される可能性があります。lpBuffer

つまり、次のように追加します。

BOOL rc;

そしてあなたの2つを変更してください:

InternetReadFile(hURL, file, 100, &read);

へのステートメント:

rc = InternetReadFile(hURL, file, 100, &read);

次に、ループは次のようになります。

while ((!rc) || (read > 0))   // I *think* that's right.
于 2010-10-22T02:49:48.470 に答える
6

少しの出力を行うには、おそらく少し時間がかかります。その間に、ネットからデータが到着し、次の への呼び出しで読み取る準備が整いますInternetReadFile

私はその獣を使用していませんが、他の読み取り関数と同じように機能する場合、必ずしも 100 バイトを読み取るとは限りません。

read == 100その場合は、ループの継続条件として使用しないでください。などを使用しread > 0ます。ただし、ドキュメントを確認してください。何が期待できるかがわかります。

その関数がどの程度低レベルであるかによっては、0 バイトの読み取りが完了したことを意味しない場合もあります。戻り値を確認する必要があるかもしれません。そして、例えば、先に進む前に少し遅れてください。

乾杯 & hth.,

于 2010-10-22T02:56:58.253 に答える