I am using OpenCV and I need to convert Iplimage->ID to char[ ] so that I can send it using TCP and then reconvert it to int on the server.
Here is the Iplimage header:
typedef struct _IplImage
{
int nSize;
int ID; //<--- ID of type INT
int nChannels;
int alphaChannel;
int depth;
char colorModel[4];
char channelSeq[4];
int dataOrder;
int origin;
int align;
int width;
int height;
struct _IplROI *roi;
struct _IplImage *maskROI;
void *imageId;
struct _IplTileInfo *tileInfo;
int imageSize;
char *imageData;
int widthStep;
int BorderMode[4];
int BorderConst[4];
char *imageDataOrigin;
}
IplImage;
this is my code:
char IDbuffer[10];
snprintf(IDbuffer,10,"%e",frame->ID);//where frame is of type IplImage*
printf("frame->ID= %a\n",IDbuffer);
and this what I got printed:
frame->ID= 0x0.0000000037d0cp-1022
even trying
printf("frame->ID= %a\n",frame->ID);
give me the same output.
Is this an integer format ?? and if yes how could I convert the char * of this format to an int??
Thanks in advance.
Use the %d format specifier since frame->ID is an integer:
snprintf(IDbuffer,10,"%d",frame->ID);
And then use the %s format specifier to print the buffer:
printf("frame->ID= %s\n",IDbuffer);
There's more information about the format specifiers in printf man page.
%e format specifier requires an argument of type double, while you are passing an int instead. The resultant behavior is undefined. That's all there is to it.
By using %e you are making a promise to snprintf. You promise that you will supply a double argument in the corresponding position. Later you break that promise by supplying an int instead of double, which leads to a meaningless result. You are essentially lying to snprintf about the type of frame->ID.
%a also requires a double argument. Why do you insist on using double format specifiers with a int argument? How do you expect this to work?
Either supply an argument of correct type (which is double), or use the proper format specifier (which is %d for int). Either this or that. Mixing things up like you do will not achieve anything.
You need cast ID to double before printing it:
snprintf(IDbuffer,10,"%e", (double)frame->ID);
Alternatively, you can print it as integer:
snprintf(IDbuffer,10,"%d", frame->ID)
Check this for more information on snprintf
Related
The following code used to compile fine. I migrated the project to a new version and now the compiler is complaining about one of my sprintf arguments. Here is the warning:
warning: format '%02d' expects type 'int', but argument 12 has type 'double'
FYI, the IDE is MPLAB X 2.35 and the compiler is XC 1.34. I have optimizations turned off and I have tried clean/build. I can only suspect that maybe the struct alignment is out of whack. I am hoping I am just missing the obvious, such as not being able to count.
Offending code:
typedef struct _AnalysisEvent
{
unsigned short id;
unsigned char day;
unsigned char month;
unsigned char year;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned int duration;
double min;
double max;
double avg;
} AnalysisEvent;
AnalysisEvent AnalysisEvents[ANALYSIS_MAX_COUNT][ANALYSIS_EVENTS_MAX_COUNT];
unsigned char AnalysisEventGetValueStrAlt(unsigned short id, unsigned char index, char *buffer, int length)
{
if (Analysis[id].count > index)
{
sprintf(buffer, "Analysis ID: %d\r\nEvent ID: %d\r\nMin: %.2f\r\nMax: %.2f\r\nAvg: %.2f\r\nTime: %02d/%02d/%02d %02d:%02d:%02d\r\nDuration: %d\r\n",
id,
index,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].max,
AnalysisEvents[id][index].avg,
AnalysisEvents[id][index].month,
AnalysisEvents[id][index].day,
AnalysisEvents[id][index].year,
AnalysisEvents[id][index].hour,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].second,
AnalysisEvents[id][index].duration
);
return index;
}
else
{
return 0;
}
}
Argument 12 is:
AnalysisEvents[id][index].min,
You probably want:
AnalysisEvents[id][index].minute,
In your case, the offending part is
%02d/%02d/%02d %02d:%02d:%02d\r\
^^^
The corresponding argument is AnalysisEvents[id][index].min, type double. You used %d.
FWIW, maybe the answer you want is
"the argument number in the warning message is the total of the ones supplied to sprintf(), counting from buffer itself, not only the ones supplied as the argument to the format."
I expect ouput something like \9b\d9\c0... from code below, but I'm getting \ffffff9b\ffffffd9\ffffffc0\ffffff9d\53\ffffffa9\fffffff4\49\ffffffb0\ffff
ffef\ffffffd9\ffffffaa\61\fffffff7\54\fffffffb. I added explicit casting to char, but it has no effect. What's going on here?
typdef struct PT {
// ... omitted
char GUID[16];
} PT;
PT *pt;
// ... omitted
int i;
for(i=0;i<16;i++) {
printf("\\%02x", (char) pt->GUID[i]);
}
Edit: only casting to (unsigned char) worked for me. Compiler spits warnings on me when using %02hhx (gcc -Wall). (unsigned int) had no effect.
The reason why this is happening is that chars on your system are signed. When you pass them to functions with variable number of arguments, such as printf (outside of fixed-argument portion of the signature) chars get converted to int, and they get sign-extended in the process.
To fix this, cast the value to unsigned char:
printf("\\%02hhx", (unsigned char) pt->GUID[i]);
Demo.
Use:
printf("\%02hhx", pt->GUID[i]);
Because printf() is a variadic function, its arguments are promoted to int. The hh modifier tells printf() that the type of the corresponding value is unsigned char and not int.
Cast to unsigned char instead, to avoid a leading 1 bit being interpreted as a negative value.
I noticed that you were getting the F's when the number was larger than 99x.
I wrote this to test it out and discovered the hh prefix at http://www.cplusplus.com/reference/cstdio/printf/
#include "stdio.h"
char GUID[16];
int main() {
int i;
for(i=0;i<16;i++) {
GUID[i]=i*i;
}
for(i=0;i<16;i++) {
printf("\\%02.2hhx\n", GUID[i]);
}
return 0;
}
Use a small own implementation to solve this problem on all platforms:
char hex[] = "0123456789abcdef";
void printHex(unsigned char byte) {
printf("%c%c", hex[byte>>4], hex[byte&0xf]);
}
I have some problems in my code:
UINT8 PoWerSignal = MyScanResults.signal;
char Signal[8];
sprintf(Signal, "%d", PoWerSignal);
float decibel = 0;
decibel = 10 * log(Signal);
dbgwrite("SIGNAL: ");
_dbgwrite(decibel);
There is one error:
error: incompatible type for argument 1 of 'logf'
I don't know how to fix this or what it means.
Your are passing a char array (aka "string", here: Signal, the alphanumerical representation of the value stored in PoWerSignal) to log(), which most likely does not expect such input, but a number.
You might like to pass the numerical representation of the function log()like so:
#include <stdio.h> /* To have the prototypes foe the printf family of functions. */
...
UINT8 PoWerSignal = MyScanResults.signal;
char Signal[8] = "";
snprintf(Signal, sizeof(Signal), "%d", PoWerSignal);
float decibel = 10. * log(PoWerSignal);
...
The function _dbgwrite() seems to expect an char array on the other hand. To conform to this create the a "string" using snprintf() out of decibel to pass into it, like so:
...
char descibel_str[64] = "";
snprintf(decible_str, sizeof(decibel_str), "%f", (double) decibel);
dbgwrite("SIGNAL: ");
_dbgwrite(decibel_str);
Note on the usage of snprintf() instead of sprintf(): The former version of this "conversion" function does take care of not overflowing the target buffer, that is where the alphanumerical representation of the arguments passed are stored. This can easely happend and would provoke undefined behaviour.
Looks like you're sending a bad data type (signal). Perhaps this should be a float or unsigned int instead of a character array? "char" denotes a string of text, and you can't operate on it as a number.
I have a struct, well pointer to a struct, and I wish to printf the first n bytes as a long hex number, or as a string of hex bytes.
Essentially I need the printf equivalent of gdb's examine memory command, x/nxb .
If possible I would like to still use printf as the program's logger function just variant of it. Even better if I can do so without looping through the data.
Just took Eric Postpischil's advice and cooked up the following :
struct mystruc
{
int a;
char b;
float c;
};
int main(int argc, char** argv)
{
struct mystruc structVar={5,'a',3.9};
struct mystruc* strucPtr=&structVar;
unsigned char* charPtr=(unsigned char*)strucPtr;
int i;
printf("structure size : %zu bytes\n",sizeof(struct mystruc));
for(i=0;i<sizeof(struct mystruc);i++)
printf("%02x ",charPtr[i]);
return 0;
}
It will print the bytes as fas as the structure stretches.
Update : Thanks for the insight Eric :) I have updated the code.
Try this. Say you have pointer to struct in pstruct.
unsigned long long *aslong = (unsigned long long *)pstruct;
printf("%08x%08x%08x%08x%08x%08x%08x%08x",
aslong[0],
aslong[1],
aslong[2],
aslong[3],
aslong[4],
aslong[5],
aslong[6],
aslong[7],
);
As Eric points out, this might print the bytes out-of-order. So it's either this, or using unsigned char * and (having a printf with 64 arguments or using a loop).
I have strange program behavior while trying to read a value from a structure after assigning a value to it. I'm showing the related structure and function below:
/*Data struct for cor_entry */
struct cor_entry {
struct cor_entry * pre_entry;
struct cor_entry * next_entry;
long long unsigned int entry_data;
};
I've commented out most of my function to highlight the problem:
/* update correlation table */
void cor_table_update(long long unsigned int cor_table_data,
struct cor_entry **cor_table_head_ptr,
struct cor_entry **cor_table_tail_ptr,
int *entry_num,
const int MAX_NUM)
{
struct cor_entry *cor_table_entry;
int cor_hit=0;
//test code
//cor_table_head=cor_table_tail=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
//printf("original cor_entry_num=%d\n",*entry_num);
////////////////////////code for test///////////////////////////////
cor_table_entry=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
printf("The cor_table_entry=%x\n",cor_table_entry);
cor_table_entry->entry_data=cor_table_data;
if (cor_table_entry->entry_data==cor_table_data)
{
printf("The assignment is correct!\n");
printf("the cor_enrty_data=%x, stored data=%x,\n",
cor_table_data,
cor_table_entry->entry_data);
}
// ... rest of function
}
And I get this output while running the program:
The cor_table_entry=8c09a58
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a70
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a88
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09ae8
Could someone shed some light on this problem? I'm using the GCC-3.4.6 compiler.
Try to compile with -Wall. GCC should then tell you that the sizes of the % format specifiers and the printf() arguments don't match. Try %llx instead of %x. That should fix the issue.
Your problem is probably with the printf, %x is not designed for showing long long unsigned. Split the value before printing it and it shall be what you expect.
You could also use %llx format specifier if your compiler support it.