Printing int type with %lu - C+XINU

I have a given code, in my opinion there is something wrong with that code: I compile under XINU.

The next variables are relevant :

unsigned long ularray[];
int num;
char str[100];

There is a function returns int:

int func(int i)
    return ularray[i];

now the code is like this:

num = func(i);
sprintf(str, "number = %lu\n", num);

The problem is I get big numbers while printing with %lu, which is not correct.

If i change the %lu to %d, i get the correct number. For example: with %lu i get 27654342, while with %d i get 26, the latter is correct;

The variables are given, the declaration of the function is given, i write the body but it must return int;

My questions are:

  1. I'm not familiar with 'sprintf' maybe the problem is there?

  2. I assigned unsigned long to int and then print the int with %lu, is That correct?

  3. How can i fix the problem?

Thanks in advance.

Thanks everyone for answering. I just want to mention I'm working under XINU, well i changed the order of the compilation of the files and what you know... its working and showing same numbers on %lu and %d.

I'm well aware that assigning 'unsigned long' to int and then printing with %lu is incorrect coding and may result loss of data. But as i said, the code is given, i couldn't change the variables and the printing command.

I had no errors or warnings btw. I have no idea why changing the compilation order fixed the problem, if someone have an idea you are more then welcome to share.

I want to thank all of you who tried to help me.


I assigned unsigned long to int and then print the int with %lu, is That correct?

No, it isn't correct at all. Think about it a bit! Printf tries to access the memory represented by the variables you pass in and in your case, unsigned long is represented on more bits than int, hence when printf is told to print an unsigned int, it'll read past your actual int and read some other memory which is probably garbage, hence the random numbers. If printf had a prototype mentioning an unsigned long exactly, the compiler could perform an implicit cast and fill the rest of the unwanted memory with zeroes, but since it's not the case, you have to do either one of these solutions:

One, explicit cast your variable:

printf("%lu", (unsigned long)i);

Two, use the correct format specifier:

printf("%d", i);

Also, there are problems with assigning an unsigned long to an int - if the long contains a too big number, then it won't fit into the int and get truncated.

1) the misunderstanding is format specifiers in general

2) num is an int -- therefore, %d is correct when an int is what you want to print.

3) ideally

  • int func(int i) would be unsigned long func(size_t i)
  • and int num would be unsigned long num
  • and sprintf(str, "number = %d\n", num); would be sprintf(str, "number = %lu\n", num);

that way, there would be no narrowing and no conversions -- the type/values would be correctly preserved throughout execution.

and to be pedantic, printf should be printf("%s", str);

if you turn your warning levels way up, your compiler will warn you of some of these things. i have been programming for a long time, and i still leave the warning level obnoxiously high (by some people's standards).

If you have an int, use %d (or %u for unsigned int). If you have a long, use %ld (or %lu for unsigned long). If you tell printf that you're giving it a long but only pass an int, you'll print random garbage. (Technically that would be undefined behavior.)

It doesn't matter if that int somehow "came from" a long. Once you've assigned it to something shorter, the extra bytes are lost. You only have a int left.

I assigned unsigned long to int and then print the int with %lu, is That correct?

No, and I suggest not casting to int first or else simply using int as the array type. It seems senseless to store a much larger representation and only use a smaller one. Either way, the sprint results will always be off until you properly pair the type (technically the encoding) of the variable with the format's conversion specifier. This means that if you pass an unsigned long, use %ul, if it's an int, use either %i or %d (the difference is that %d is always base-10, %i can take additional specifiers to print in other bases.

How can I fix the problem?

Change the return of your func and the encoding of num to unsigned long

unsigned long ularray[];
unsigned long num;
char str[100];

unsigned long func(int i)
    return ularray[i];

Need Your Help

Passing the file data into function

java file snmp

Hi I have been trying to pass the ipAdresses which are in a file to a SNMP function which will perform a GET Operation. I am reading the file line by line and passing the data. But I am getting an ...

How to do something to each file in a directory with a batch script

windows file loops batch-file cmd

How do you iterate over each file in a directory with a .bat or .cmd file?