我有这段代码在调试期间不断抛出“缓冲区太小”的错误。
geoGraph.size=limit;
CString xAxis ="X axis: ",yAxis="Y axis: ";
for (int x = 0; x < limit; x++)
{
xAxis.Format(_T("%s%i "),xAxis,(x+1));
yAxis.Format(_T("%s%s "),yAxis,dialog_test.str[x]);
}
xAxis.Format(_T("%s \n%s "),xAxis,yAxis);// <---Error thrown
d.SetWindowTextA(xAxis);
我得出结论,错误是由于Cstring xAxis太小而无法包含新文本,我是否正确,如果是,我该如何解决?
感谢。
编辑:我很好奇为什么这个错误只在调试期间显示,而不是在我使用'start without debugging'运行应用程序时(我使用的是VS2008)。
答案 0 :(得分:8)
没有!真正的问题是:
永远不要在格式中使用CString作为目标AND源! 这可能在Release Version中有效,因为Memory MIGHT不会被更改,但是如果它被更改,则行为是未定义的。但这是一个真正糟糕的编码错误。
答案 1 :(得分:2)
CStringT::Format的文档包含以下注释:
如果字符串对象本身作为Format的参数提供,则调用将失败。例如,以下代码将导致不可预测的结果:
CAtlString str = _T("Some Data"); str.Format(_T("%s%d"), str, 123); // Attention: str is also used in the parameter list.
要解决此问题,您可以为参数创建副本,或者 - 在此特定情况下 - 调用CStringT::AppendFormat类成员:
geoGraph.size = limit;
CStringW xAxis = L"X axis: ",
yAxis = L"Y axis: ";
for ( int x = 0; x < limit; ++x ) {
xAxis.AppendFormat( L"%i ", x + 1 );
yAxis.AppendFormat( L"%s ", dialog_test.str[x].GetString() );
}
xAxis.AppendFormat( L" \n%s ", yAxis.GetString() );
特别注意,此实现调用CSimpleStringT::GetString来检索C样式字符串以与%s
格式说明符一起使用。为CString
占位符传递%s
对象未记录为 * 。
另请注意,此实现使用CString对象的显式宽字符版本以及宽字符串文字。所有受支持的Windows版本都使用Unicode(UTF-16)作为其本机编码。因此,在应用程序中使用Unicode是一种自然的选择。
<小时/> * 所有当前支持的ATL / MFC版本以允许在期望C样式字符串的任何地方传递
CString
对象的方式实现CString
。这也适用于变量参数列表。后者是实施细节,而不是记录合同的一部分。不应该依赖它。
答案 2 :(得分:1)
如果你的目标是重用变量,你可以这样做:
geoGraph.size=limit;
CString xAxis ="X axis: ",yAxis="Y axis: ";
for (int x = 0; x < limit; x++)
{
xAxis.Format(_T("%s%i "), CString(xAxis),(x+1));
yAxis.Format(_T("%s%s "), Cstring(yAxis),dialog_test.str[x]);
}
xAxis.Format(_T("%s \n%s "), CString(xAxis),yAxis);
d.SetWindowTextA(xAxis);
我有类似的情况并且它有效,因为我现在正在使用xAxis变量的副本而不是直接。
答案 3 :(得分:-1)
问题解决了。使用;
xAxis.AppendFormat(_T("\n%s "),yAxis);