Incorrect result for% p when implementing printf

I am working on my own printf code, and I have two problems that I was hoping you could help me.

The first option with the %p parameter:

This option gives me the address of the void* pointer in hexadecimal form. So what I do is:

 void printp(void *thing) { dectohex((long)&thing, 1); } 

where dectohex is just a function that converts a decimal to hex . The result will always be correct, with the exception of the last three characters. Always. For example:

 me : 0x5903d8b8 , printf : 0x5903da28. 

And these characters do not change very often, while the other part changes with each call, as intended.

Another issue I ran into is with the %O option. I am unable to convert the signed int to unsigned int . printf prints huge numbers for negative int's , and no throws seem to work, since I would not have a place to store it.

EDIT: Thanks so much for the answers, so apparently for the first problem I was just a little stupid. In the second question, I am going to try the various solutions that you gave me and update if I manage to do this.

Thanks again for your time and patience, and sorry for the delay in my reply, I checked the email alert for a response, but this does not work.

REEDIT: after reading your answers to my second question more carefully, I think some of you think I asked about% o or% 0. I really talked about% O, like in% lo, I think. In a person, he tells me "% O: a long int argument is converted to unsigned octal code." My problem is to convert a long int to octal, I need to convert it to something unsigned.

+8
c printf
source share
4 answers

If uintptr_t/intmax_t defined (optional), convert the pointer to this integer type and then print.

Otherwise, if sizeof(uintmax_t) >= sizeof (void *) , go to uintmax_t . uintmax_t is the required type, but may not be large enough.

 void printp(void *thing) { uintptr_t j = (uintptr_t) thing; char lst[(sizeof j * CHAR_BIT + 3)/ 4 + 1]; // Size needed to print in base 16 char *p = &lst[sizeof lst] - 1; *p = '\0'; do { p--; *p = "0123456789ABCDEF"[j%16]; j /= 16; } while (p > lst); fputs(p, stdout); } 

The %O problem is probably a sign extension problem. (@mafso) Commit used unsigned values, such as unsigned and unsigned long . Not knowing that the code is hard to understand for sure.

+3
source share

About the first problem you have, just to make sure you want to type the address of the thing (note that the thing itself is a pointer) or the address of the object's origin (pointer to the thingโ€™s pointer)?

You are currently printing a pointer to a pointer.

Edit

 dectohex((long)&thing, 1); 

to

 dectohex((long)thing, 1); 

if so.

About %O problem, can you give some sample code?

+2
source share

You need an "unsigned long long" for your cast.

Pointers are unsigned, but long signed.

The number of bits in any data type depends on the implementation; however, these days for a long and unsigned one there are 32 bits long.

edit: to be more clear, you cannot count on anything about the number of bits in C, C ++ or Objective-C, it always depends on the implementation. For example, it was once common to have nine bits of bytes and thirty-six bits of words. This is why Internet protocols always indicate "octets" - groups of eight bites, not "bytes."

This is one of the advantages of Java, because the number of bits in each data type is strictly defined.

+1
source share

About your second question on zero padding and negative integers, which seems completely separate from the first question on hex output. You can handle negative numbers like this (although in 32-bit mode it does not work with a value of -2147483648, which is 0x80000000).

 #include <stdio.h> #define MAXDIGITS 21 int printint(int value, int zeropad, int width) { int i, z, len = 0; char strg [MAXDIGITS+1]; strg [MAXDIGITS] = 0; if (value < 0) { value = - value; putchar ('-'); len = 1; } for (i=MAXDIGITS-1; i>=0; i--) { strg [i] = '0' + value % 10; if ((value /= 10) == 0) break; } if (zeropad) for (z=MAXDIGITS-i; z<width; z++) { putchar ('0'); len++; } for (; i<MAXDIGITS; i++) { putchar (strg [i]); len++; } return len; } int main (int argc, char *argv[]) { int num = 0, len; if (argc > 1) { sscanf (argv[1], "%d", &num); // try the equivalent of printf("%4d, num); len = printint (num, 0, 4); printf (" length %d\n", len); // try the equivalent of printf("%04d, num); len = printint (num, 1, 4); printf (" length %d\n", len); } return 0; } 
0
source share

All Articles