将CString传递给fprintf

时间:2014-02-11 10:51:55

标签: c++ mfc portability cstring printf

我已经在Visual Studio上运行了代码分析器,在大型代码库上运行了大约10亿这个错误:

warning C6284: Object passed as parameter '3' when string is required in call to 'fprintf'

根据http://msdn.microsoft.com/en-us/library/ta308ywy.aspx“此缺陷可能会导致输出错误或崩溃。”然而,我的同事说我们可以毫无问题地忽略所有这些错误。所以我的一个问题是我们是否需要对此做任何事情,或者我们可以保留原样吗?

如果需要解决这些错误,最好的解决方法是什么?

这样做是否可行:

static_cast<const char*>(someCString)

对此有更好或更正确的方法吗?

以下行生成此警告:

CString str;
fprintf(pFile, "text %s", str);

3 个答案:

答案 0 :(得分:2)

我假设您将Microsoft“CString”对象传递给printf() - 族函数,其中相应的格式说明符为%s。如果我是对的,那么你的答案就在这里:How can CString be passed to format string %s?(简而言之,你的代码没问题。)

似乎最初的实现细节允许CString直接传递给printf(),后来它成为合同的一部分。所以你很高兴你的程序正确,但如果你想避免静态分析警告,你可能确实需要使用static_cast到char指针。我不确定它在这里是否值得...也许还有其他方法可以让这些工具放在一起,因为它们都来自微软。

答案 1 :(得分:2)

根据C6284中的MSDN建议,您可以抛弃警告。使用C ++强制转换是最易于维护的选项。您上面的示例将更改为

fprintf(pFile, "text %s", static_cast<const TCHAR*>(str));

或者,只是另一种拼写,

fprintf(pFile, "text %s", static_cast<LPCTSTR>(str));

最有说服力的选项 100%无广告,请参阅编辑部分)

fprintf(pFile, "text %s", str.GetString());

当然,遵循任何这些更改模式将是第一个移植步骤,如果没有任何表明需要它,这可能是有害的(不仅仅是你的团队氛围。)


编辑:(根据xMRi的评论)

1)我添加了const,因为该参数对于fprintf

是只读的

2)对免铸解决方案CSimpleStringT::GetString的说明:CSimpleStringT类模板用于CStringT的定义,该模板再次用于键入定义类CString用于原始问题

3)重新设计了消除噪音的答案。

4)减少关于铸造选项的介绍

答案 2 :(得分:0)

从技术上讲,它是可以的,因为c-string以这种方式存储在CString中,您可以按照说明使用它,但是依赖CString如何实现快捷方式并不好。 printf是一个C-runtime函数,对C ++对象一无所知,但这里依赖的是字符串首先存储在CString中 - 一个实现细节。

如果我没记错,最初CString无法以这种方式使用,并且必须将CString转换为c-string以将其打印出来,但在以后的版本中,MS更改了实现以允许将其视为c-字符串。

另一个突破性问题是UNICODE,如果你有一天决定使用UNICODE字符集编译程序肯定不会起作用,因为即使你将所有字符串格式化程序更改为%ld,嵌入式0也有时会阻止字符串被打印。

实际问题是为什么使用printf而不是C ++来打印/写入文件?