簡體   English   中英

奇怪的C ++ std :: string行為...我該如何解決?

[英]Strange C++ std::string behavior… How can I fix this?

這讓我發瘋。 我已經花了兩個多小時試圖找出答案...

這是我的問題。 我正在開發一個適用於貝葉斯網絡的大型程序。 這是主要功能:

using namespace std;

int main()
{  
    DSL_network net;
    initializeNetwork(net); 
    setEvidence(net);
    net.SetDefaultBNAlgorithm(7);
    net.SetNumberOfSamples(80000);
    cout << "Samples:\t" << net.GetNumberOfSamples() << endl;
    updateEvidence(net);
    //net.WriteFile("test.dsl");
    return(DSL_OKAY);
}

這一切都很好。 當我想打印一個字符串時,問題就來了:

using namespace std;

int main()
{  
    //simple string creation
    string a = "test";
    //should print out "test"
    cout << a << endl;
    DSL_network net;
    initializeNetwork(net); 
    setEvidence(net);
    net.SetDefaultBNAlgorithm(7);
    net.SetNumberOfSamples(80000);
    cout << "Samples:\t" << net.GetNumberOfSamples() << endl;
    updateEvidence(net);
    //net.WriteFile("test.dsl");
    return(DSL_OKAY);
}

這是輸出(只是通過打印字符串a ...):

▀ÇΦy♠≈6♦

可能會發生什么?

更新:

int main()
    {  
        //simple string creation
        string a = "test";
        //should print out "test"
        cout << a << endl;
        return(DSL_OKAY);
    }

仍然打印

▀ÇΦy♠≈6 ♦

大更新:這是最近的。 我創建了一個全新的項目,並粘貼了尼爾·巴特沃思(Neil Butterworth)發布的代碼(感謝順便說一句)。 我運行了代碼,它可以正確打印。 然后,我將兩個.lib文件添加到新項目的鏈接器中(SMILE庫為smile.lib,套接字使用為wsock32.lib)。

我再次嘗試了該代碼,並正確地打印了第一個“測試”,然后打印出了無聊的地方。 我鏈接在一起的.lib之一存在問題。 我自己嘗試了每個嘗試,看看它們是否只是發生沖突,似乎smile.lib庫正在引起問題。 我將需要查看他們的文檔並找出原因。

有任何想法嗎?

謝謝大家的幫助

謝謝

真奇怪 我總是喜歡將問題分解為最小的案例。 當您運行以下程序時,它會做什么?

using namespace std;
int main() {  
    string a = "test";
    cout << a << endl;
    return 0;
}

如果這行得通,則說明存在其他問題,您需要一次添加一行直到失敗。 然后, 非常仔細地檢查該行(“我正在尋找wabbits”)。

根據您的編輯,它可能是一個不同的字符串類。 嘗試這個:

int main() {  
    std::string a = "test";
    std::cout << a << std::endl;
    return 0;
}

更新:

由於它適用於新項目而不是當前項目,因此請檢查以下內容。

  • 確保與標准C ++運行時鏈接。
  • 確保不要#define其他string (並且在編譯器中包含-Dstring=somethingelse命令行選項)。
  • 使用std::string而不是string檢查行為。

也嘗試一下:

int main()
    {  
        //simple string creation
        string a = "test";
        const char* cStr = a.c_str();
        //should print out "test"
        cout << cStr << endl;
        return(DSL_OKAY);
    }

如果const char*行沒有引起編譯器錯誤,那么我們知道std::str是8位字符串。 如果cout不會導致編譯器錯誤,那么我們知道cout是為8位字符定義的。 (而且,如果程序產生相同的結果,那么我們仍然很困惑:-}

編輯 (根據下面的評論):我注意到“測試”的越野車輸出結果為9個字符-“▀ÇΦy♠≈6♦”。 嘗試其他“測試”字符串,例如,“ retest”或“ foo”。 我懷疑您的輸出通常是原始字符串中字符數的2x或2x + 1(“ retest”為12或13,“ foo”為6或7。)這表明您正在提供16位字符串放入8位緩沖區 不過,我不知道如何才能通過編譯器—也許您對std :: string和/或cout的定義有誤或過時?

編輯2 :我記得我以前看過哪里。 幾年前,我看到一個問題,其中DOS控制台窗口損壞了程序的輸出。 (我不記得確切的詳細信息,但我認為問題是DOS控制台無法處理UTF-8字符集。)如果您在DOS窗口中看到此輸出(或者,不太可能,則是通過system()傳遞到另一個程序),然后嘗試將其重定向到文件,然后使用記事本打開該文件。 它可能會起作用...

檢查是否

  • 您是否有#include<iostream>和其他相關標頭包含?
  • net.GetNumberOfSamples()具有有效值,並且
  • 您沒有混合使用stringwstring

您是否100%認為源代碼文件是ASCII? 嘗試在一些十六進制編輯器中打開它。

嘗試在一個全新的文件中鍵入(而不是復制/粘貼)代碼,然后看看會發生什么。

如果失敗了,那么顯然您的建議會有所修改。 您能告訴我們哪些庫鏈接到可執行文件嗎? 也許某些東西關閉了stdout流或類似的東西。

我建議您慢慢刪除所有#include,直到找到導致該問題的一個。

您可以嘗試為字符串類型顯式指定std名稱空間。

建議您嘗試此操作的主要理由是,在其中包含的某些頭文件中可能有一個定義,該定義將字符串替換為其他類或定義。 添加名稱空間應強制不使用該宏。

要檢查的另一件事是獲取寫出到文件中的源代碼的處理過的清單(或匯編和源清單,如果您想進行匯編黑客攻擊),然后檢查該清單以查看發生了什么。如果沒有別的,我可能會在那里找到答案。

編譯並運行以下確切代碼; 不要添加任何using指令。

#include <iostream>
#include <string>

int main() {
    std::string s = "test";
    for ( unsigned int i = 0; i < s.size(); i++ ) {
        std::cout << s[i];
    }
    std::cout << "\n";
    std::operator<<( std::cout, s );
    std::cout << "\n";
}

如果循環顯示“ test”,則表示字符串正確,問題出在輸出中。 如果第二個“測試”被弄亂了,那么問題肯定出在輸出處理中。

將std :: string轉換為char字符串是否起作用。 即:

cout << a << endl;

變成

cout << a.c_str() << endl;

您似乎很可能在混合wchar和char,因此在您的主目錄中固定字符被認為是寬字符(2個字節/字符)或某些unicode,並且您的cout的lib認為它們是簡單的1個字節/字符。 我將查找與項目鏈接的庫。

不幸的是,我不確定如何解決此問題。 幾乎可以肯定,您的項目可以在某個地方進行更改(不幸的是,我前面沒有VS 2005),但是您正在尋找wchar,t_char或unicode之類的東西。

我很好奇,如果您使用

string a("test");

而不是直接分配。

同一項目中另一個文件中某個地方的operator <<是否可能超載? 請嘗試搜索“ operator << ”或“ operator<< ”。

意見建議:

  • cout <<之前調用cout.flush ,以查看是否得到了奇怪的字符
  • 嘗試printf

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM