0

The sprintf is not displaying the string message appropriately. The message to be displayed is Value out of range. Range is -2147483648 and 2147483647. However it is printed as Value out of range. Range is -2147483648 and 0.

#include <iostream>
#include <string>

int main()
{
    __int64 tmpminVal = -2147483648;
    __int64 tmpmaxVal = 2147483647;

    std::string strTemp = "Value out of range. Range is %d and %i ";
    char buffer[100];
    int n = sprintf (buffer, strTemp.c_str(), tmpminVal,tmpmaxVal);
    strTemp = buffer;
    std::cout << strTemp << std::endl;
    return 0;
}

Please provide the reason why it is does so.

8
  • 2
    %d and %i are for int but you provide __int64. This causes undefined behaviour. You will need to find out what your platform's specifier is for __int64. (If you use long long instead then %lld is the specifier). Commented Aug 5, 2014 at 11:37
  • 1
    %d and %i expect an int, not an __int64. What you see is probably the effect of tmpminVal being split into two chunks of 32 bits each. Commented Aug 5, 2014 at 11:37
  • The correct format specifier for __int64 is %I64d. Commented Aug 5, 2014 at 11:39
  • thanks all. I defined the variables as long int and used the format specifier as %ld. and it is working fine. Commented Aug 5, 2014 at 12:17
  • @user657267, %I64d is not present in Linux. I wanted a general solution which works in both Windows and Linux. Commented Aug 5, 2014 at 12:18

3 Answers 3

2

You can find printf parameters.

As you see %d is signed integer, integer in this case means 32-bit. Go further to specifiers table and you will see, that to print 64-bit (long long) you need to use specifier ll, so you need %lld, not %d.


Your result (-2147483648 and 0) is Undefined Behaviour


Also as I see from comments, you want cross platform solution, so you should use long long instead of __int64, as this one is Windows type.

Sign up to request clarification or add additional context in comments.

Comments

1

You passing two long long's to a function which expects two ints. Either change %d and %i to %ll or change __int64 to int.

1 Comment

Changing the format directive from "%d" to "%ll" is certainly wrong. Suspect you meant "%lld". Even "%lld" is not a great solution. "%lld" is for long long. long long may not be the same size as __int64. MS calls for "I64d" msdn.microsoft.com/en-us/library/aa261215(v=vs.60).aspx
1

So, as the other answers also say, you're invoking undefined behavior by passing a int64 to a format string expecting an int

Instead, you should use stdint.h and inttypes.h. On Linux, these will be included, and under Windows, you can include this project to use them: https://code.google.com/p/msinttypes/

An example use would be:

#include <iostream>
#include <string>
#include <inttypes.h>
#include <cstdint>

int main()
{
    int64_t tmpminVal = -2147483648;
    int64_t tmpmaxVal = 2147483647;

    std::string strTemp = "Value out of range. Range is %" PRId64 " and % " PRIi64 " ";
    char buffer[100];
    int n = sprintf (buffer, strTemp.c_str(), tmpminVal,tmpmaxVal);
    strTemp = buffer;
    std::cout << strTemp << std::endl;
    return 0;
}

You can also find some documentation about these header files at cppreference: http://en.cppreference.com/w/c/types/integer

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.