我正在写一些逻辑来做一些日志记录,有一堆C ++与C混合,因为这个库的大部分都是p / Invoked。我设法编写了一个记录消息和可选参数的函数:
void writeToLog(char* message, char* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append(arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
然而它只需要char *作为args,但我想将它们与int和long一起使用...我试过了:
void writeToLog(char* message, void* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append((char*)&arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
但无论数据类型如何,它都会打印/写入乱码。请指出您认为合适的任何其他错误,在C / C ++方面,我有点像菜鸟。
答案 0 :(得分:2)
有两种方法可以解决这个问题。第一种方法是重载功能。这意味着您将反复编写相同的函数,除非使用不同的类型作为参数。 实施例
#include <iostream>
using namespace std;
class printData {
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void) {
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
此代码打印:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
第二个选项是使用模板。基本上,你会这样做
template<class T>
void writeToLog(char* message, T arg){
//continue to write code here without assuming anything about the type of arg
}
重载功能的链接:https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm
答案 1 :(得分:1)
我的建议:
std::to_string
将数字转换为std::string
。添加一些包装器代码,以便您可以使用相同的函数调用来处理char*
和char const*
。std::string::c_str()
的通话。可以将std::string
写入文件std::cout
。file.close();
。它将在函数返回时关闭。namespace my_app
{
template <typename T>
std::string toString(T in)
{
return std::to_string(in);
}
std::string toString(char const* in)
{
return std::string(in);
}
std::string toString(std::string const& in)
{
return in;
}
}
template <typename T>
void writeToLog(char* message, T arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
fullMessage.append(my_app::toString(arg));
fullMessage.append("\n");
file << fullMessage;
std::cout << fullMessage;
}
}
// Overload to deal with the optional parameter
void writeToLog(char* message) {
writeToLog(message, "");
}
答案 2 :(得分:1)
您可以使用模板。
这是一个简单的例子,向您展示了基本思路。 (虽未测试)
template <typename T, typename U>
void func(T param1, U param2)
{
std::cout << param1 << param2;
}
以主要为例:
func("A", 5);
func (2, 2.5);
您需要阅读一些内容才能满足您的需求。
答案 3 :(得分:1)
任何托管object
都可以封送为VARIANT
。当然,如果你这样做,你不会从编译器中进行任何类型检查。
// C# P/Invoke
static extern void writeToLog(string message, ref object arg);
// C++
void writeToLog(const char* message, const VARIANT* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg) {
switch (V_VT(arg)) {
case VT_I4:
message.append(V_I4(arg));
break;
case VT_I8:
message.append(V_I8(arg));
break;
case VT_BSTR:
message.append(V_BSTR(arg));
break;
}
}
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}