2010-10-22 67 views
2

我寫了一個簡單的程序來抓住雅虎財經的股票價格。讀取數據的循環提前截斷(並停止網站數據顯示的位置,而不是完整下載到excell文件的正確日期)。所以我在循環中加入了一個cout命令來嘗試調試,並且它正確地工作!Cout修復了C++程序中的錯誤,但是爲什麼?

那麼爲什麼使用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; 
} 
+0

你確定這正是你的代碼? 'cout <「Error ...」'看起來很可疑... – 2010-10-22 02:49:50

+0

你是對的,這是一個錯誤,但它在我的程序中(我不知道它爲什麼編譯),所以我只是將它改爲<<並仍然得到同樣的問題,cout解決了另一個問題。 (感謝您注意!) – 2010-10-22 02:53:57

+0

編碼提示:您可以通過使用do-while而不是常規while來將初始讀取合併到循環中。 – chrisaycock 2010-10-22 02:58:35

回答

7

你有什麼是「 Heisenbug「,當你試圖找到它時會消失。沒有錯,問題仍然存在,你需要需要找到它。

第一個你應該做的事情是檢查InternetReadFile的返回碼。

此外,您應該而不是假定成功讀取將返回完整的100個字節,即使將有更多。該doco狀態:

,以確保所有數據被檢索,應用程序必須繼續調用InternetReadFile函數,直到函數返回TRUElpdwNumberOfBytesRead參數等於零。

:::

此外,轉換線可能不完全填充緩衝器,所以InternetReadFile可以lpBuffer具有較少數據返回比請求。

換句話說,我想補充:

BOOL rc; 

,改變你的兩個:

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

語句:

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

那麼你的循環變成:

while ((!rc) || (read > 0)) // I *think* that's right. 
+0

布拉沃!我改變了代碼說 – 2010-10-22 03:02:39

+0

布拉沃!我改變了代碼說(蘆葦!= 0),它的工作!謝謝! – 2010-10-22 03:03:20

+2

+1對於Heisenbug – 2010-10-22 04:28:32

6

做一點輸出可能需要一點時間,在這段時間內,數據可以從網絡到達,準備在您下一次撥打InternetReadFile時讀取數據。

我沒有使用過這個野獸,但是如果它像其他讀取函數一樣工作,那麼它不一定讀取100個字節,它可能讀取的東西更少。

如果是這樣,那麼請不要使用read == 100作爲循環的延續條件。使用例如read > 0。但是請檢查文檔,它應該告訴你期望什麼。

根據函數的低級別,也可能零字節的讀取並不意味着完成。這可能是你需要檢查返回值。並且例如在繼續之前做一點延遲。

乾杯&心連心,

+0

感謝你! (布拉沃!我改變了代碼說,而(蘆葦!= 0),它的工作!)(你們很棒!) – 2010-10-22 03:04:16

+0

@GaryWhite如果這解決了你的問題,你應該接受這個答案。 – 11684 2013-01-19 12:58:32

相關問題