奇怪的 C++ std::string 行为......我该如何解决这个问题?
Posted
技术标签:
【中文标题】奇怪的 C++ std::string 行为......我该如何解决这个问题?【英文标题】:Strange C++ std::string behavior... How can I fix this? 【发布时间】:2009-04-28 05:16:26 【问题描述】:这让我发疯了。我已经研究了 2 个多小时试图弄清楚这一点......
这是我的问题。我正在开发一个与贝叶斯网络一起使用的相当大的程序。这是主要功能:
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.lib 用于 SMILE 库,wsock32.lib 用于套接字。)
我再次尝试了代码,它正确打印了第一个“测试”,然后打印了乱码。这是我链接在一起的一个 .lib 的问题。我自己尝试了每一个,看看它们是否只是冲突,似乎是 Smile.lib 库导致了这个问题。我需要查看他们的文档并找出原因。
有什么想法吗?
感谢大家的帮助
谢谢
【问题讨论】:
这有点含糊(至少在这个时候对我来说)——你是在说:'string a = "test"; cout 是否有任何#includes 也可能包含字符串类? 是的,可能有。这会是个问题吗?我会检查的 “我是一个使用贝叶斯网络的相当大的程序。”哇,我印象深刻,你写了一个有感知力的程序,它知道如何向 SO 发布它自己的问题! 我检查了#includes,没有冲突。 【参考方案1】:这很奇怪。我总是喜欢将问题分解为最小的情况。下面的程序在你运行时做了什么?
using namespace std;
int main()
string a = "test";
cout << a << endl;
return 0;
如果这样可行,那么还有其他问题,您需要一次添加一行,直到它失败。然后仔细检查那行非常(“我在打猎兔兔”)。
根据您的编辑,可能使用了不同的字符串类。试试这个:
int main()
std::string a = "test";
std::cout << a << std::endl;
return 0;
更新:
由于它适用于新项目而不是当前项目,请检查以下内容。
确保您链接的是标准 C++ 运行时。 确保您没有将string
定义为其他内容(其中包括编译器的-Dstring=somethingelse
命令行选项)。
使用std::string
检查行为,而不仅仅是string
。
【讨论】:
这都是与项目相关的......我打开了另一个项目,它工作正常。是否有一些设置是错误的?谢谢 如果您有调试器,请在打印前检查实际变量“a”。它可能不是 std::string。 std:: 版本在可疑项目中做了什么? 您使用的是哪个编译器/IDE。项目是特定于产品的。 两个字符串(正在工作的项目,和顶起一个)显示为 std::basic_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 位字符定义的。 (如果程序产生相同的结果,那么我们仍然感到困惑:-
编辑(基于您在下面的评论):我注意到“test”的错误输出为 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()
传送到另一个程序),然后尝试将其重定向到一个文件,然后用记事本打开该文件。它可能会起作用......
【讨论】:
这是我打印“a”得到的结果:ÿÿÿÿ߀èy÷6 附言。长度始终为15... ▀ÇΦy♠≈6 ♦ 前后有一些空字符【参考方案3】:检查是否
你有#include<iostream>
和其他相关的标题包括吗?
net.GetNumberOfSamples()
具有有效值 AND
你没有混合string
和wstring
。
【讨论】:
是的。假设包含正确的#include。 net.GetNumberofSamples 是问题所在。这将返回一个 int 并打印正常。【参考方案4】:您是否 100% 认为源代码文件是 ASCII?尝试在一些十六进制编辑器中打开它。
尝试在一个全新的文件中输入(而不是复制/粘贴)代码,看看会发生什么。
如果失败了,那么显然你的 cout 有什么问题。你能告诉我们哪些库链接到可执行文件中吗?也许某些东西会关闭标准输出流或类似的东西。
【讨论】:
【参考方案5】:我建议您慢慢删除所有#include,直到找到导致问题的那个。
【讨论】:
【参考方案6】:您可以尝试为字符串类型显式指定 std 命名空间。
我建议您尝试这样做的主要原因是,在某些包含的头文件中可能有一个定义,它将字符串替换为其他一些类或定义。添加命名空间应强制不使用宏。
要检查的另一件事是获取写入文件的源代码的已处理列表(或程序集和源代码列表,如果您想进行一些程序集黑客攻击)并检查它以查看发生了什么.如果不出意外,您可能会在那里找到答案。
【讨论】:
【参考方案7】:编译并运行以下确切代码;不要添加任何 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”,则表示字符串正常,问题出在输出中。如果第二个“测试”被破坏,那么问题肯定出在输出处理中。
【讨论】:
感谢您的提示。在我的帖子中查看我的重大更新【参考方案8】:将 std::string 转换为 char 字符串是否有效。 即:
cout << a << endl;
变成
cout << a.c_str() << endl;
【讨论】:
【参考方案9】:您似乎很可能正在混合 wchar 和 char,因此在您的主要固定字符被认为是宽的(2 字节/字符)或一些 unicode,并且您的 cout 库认为它们是简单的 1 字节/字符。我会查看与项目链接的库。
不幸的是,我不确定如何解决这个问题。几乎可以肯定,您可以更改项目的某个设置(不幸的是,我面前没有 VS 2005),但您正在寻找诸如 wchar、t_char 或 unicode 之类的东西。
我很好奇如果你使用会发生什么
string a("test");
而不是直接分配。
【讨论】:
【参考方案10】:是否有可能在同一个项目的另一个文件中的某个位置,operator <<
被重载?
请尝试搜索“operator <<
”或“operator<<
”。
【讨论】:
【参考方案11】:建议:
在您的cout <<
之前致电cout.flush
,看看您是否得到了奇怪的字符
试试printf
【讨论】:
以上是关于奇怪的 C++ std::string 行为......我该如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章
扣除 string_view 的 std::make_pair 的一些奇怪行为
C++ 字符连接与 std::string 行为。请解释一下
在 C++ 中比较两个 std::string 时的未定义行为 [关闭]