最近用惯了JAVA的“强大”的“toString( )”方法,因为开始要接触NDK,在C里面打Log确实让我着急了一番。
好怀念:Log.i(TAG, "this is " + int + float + double + boolean + ..... + son of Object + grand son of Object + .....);
一看C,想这样偷懒,太不容易了。。。万般不爽之余,我盯上了printf(format, .....);
printf(char* format, ...)这是一个可变参数的打印函数,是否可以改造一下呢?
最终我选择:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
char* intToChars(int i)
{
static char intResult[11] = {0};
sprintf(intResult, "%d", i);
return intResult;
}
char* floatToChars(float f)
{
static char floatResult[11] = {0};
sprintf(floatResult, "%f", f);
return floatResult;
}
char* doubleToChars(double d)
{
static char doubleResult[21] = {0};
sprintf(doubleResult, "%lf", d);
return doubleResult;
}
char* boolToChars(int b)
{
static char boolResult[3][6] = {"false","true","other"};
if(b == 0) return boolResult[0];
else if(b == 1) return boolResult[1];
else return boolResult[2];
}
#define MSG_LENGTH 256
#define E "E"
char message[MSG_LENGTH];
char* prepareMsg(char* first,...){
memset(message, 0 , MSG_LENGTH);
va_list arg_ptr;
char* nArgValue = first;
va_start(arg_ptr,first);
do
{
strcat(message, nArgValue);
nArgValue = va_arg(arg_ptr, char*);
} while(strcmp(nArgValue, E));
return message;
}
通过最后一个函数,将常见类型转为字符串,打印出来供查看。
当然,不足之处也很显见:结束字符串必为“E”(否则会出错!), 整体字符串长度未作检查, 其它类型未添加(不过后期可以完善)
测试代码如下:
int main()
{
printf("hello, world\n");
printf("int.length = %d \n", sizeof(int));
printf("long.length = %d \n", sizeof(long int));
printf("float.length = %d \n", sizeof(float));
printf("double.length = %d \n", sizeof(double));
printf("longlongint.length = %d \n", sizeof(long long int));
printf("int 1234 = %s\n", intToChars(1234));
printf("float 1234.56 = %s\n", floatToChars(1234.56f));
printf("double 123456.7890 = %s\n", doubleToChars(123456.7890));
printf("bool 1 = %s\n", boolToChars(1));
printf("\ntest variable = %s\n",
prepareMsg( " int 1234 = ", intToChars(1234),
" float 1234.56f = ", floatToChars(1234.56f),
" double 123456.7890 = ", doubleToChars(123456.7890),
" bool 1 = ", boolToChars(1),
E));
return 0;
}
结果如下:
不过在一开始,我犯了一个错误:妄图仅根据不定参数的地址来判断参数是否结束。
即上述while( )条件为: while(nArgValue != NULL)
结果是遇上了“Segmentation fault”,最后不得不诉诸于素未谋面的GDB,
大致过程 :
1.开始调试:gdb hello
2.重现错误:run
3.错在哪里?where
4.调用堆栈:bt
5.定位断点:b line / b funcName
6.退出调试:quit / q
GDB, 后会有期!