1

I am getting weird output after sorting

If giving input using scanf the line is causing error. The output is in some weird arrangement. (I have commented the line)

If I use cin the output is fine. Also the problem is not present in online compilers. Same thing is happening on different computers.

Eg if I input

5
23 44 32 2 233

the output is

32 23 233 2 44

Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iomanip>


using namespace std;

int main()
{
    unsigned long long int n=0,i=0;

    // cin>>n;
    scanf("%llu",&n);

    unsigned long long int arr[n];

    for(i=0;i<n;i++)
    {
        // cin>>arr[i]; //if use this no error but if use next line it is
        scanf("%llu",&arr[i]); //causing error
    }

    sort(arr,arr+n);

    for(i=0;i<n;i++)
    {
        // cout<<arr[i]<<" ";
        printf("%llu ",arr[i]);
    }
    return 0;
}
p.i.g.
  • 2,815
  • 2
  • 24
  • 41
  • 1
    Did you try stepping through the code in your debugger ? – Paul R May 18 '15 at 08:45
  • 4
    Take a look at Michael Burr's answer to [Strange “unsigned long long int” behaviour](http://stackoverflow.com/a/5997384/1241334) – Jonny Henly May 18 '15 at 08:54
  • @swapnilansh As for me then it works well if the compiler supports variable length arrays. – Vlad from Moscow May 18 '15 at 09:10
  • @swapnilansh Also I am sure that the problem has nothing common with scanf because the output shows correct values though they are not sorted in your post. – Vlad from Moscow May 18 '15 at 09:14
  • 1
    What compiler/environment are you using? – axxis May 18 '15 at 09:23
  • your code works well on my Windows system. I guess there's something wrong with your compiler, or your environment. – David S. May 18 '15 at 09:27
  • You might try checking the `scanf` return value too - it will tell you if it it doesn't think the input can be parsed according to the specified flag. And in light of link from Jonny, the obvious question is are you using MinGW? – Tony Delroy May 18 '15 at 09:28
  • @axxis I am using code blocks 13.12 MinGW on windows xp –  May 18 '15 at 14:10
  • I assume this is a 32bit system. In this case check the answers below and also http://stackoverflow.com/questions/5997258/strange-unsigned-long-long-int-behaviour/5997384#5997384 as pointed out by Jonny Henly – axxis May 18 '15 at 14:28

3 Answers3

0

If using cin helps, then probably %llu is wrong flag for given pointer. Check documentation for your compiler and see what long long means for it and check printf/scanf doc of your library.

Hcorg
  • 11,598
  • 3
  • 31
  • 36
0

What probably happens is that %llu is wrong for your compiler.
For example, if you compile your program with g++ in MinGW using the -Wall flag in order to get all the warnings, you get this:

a.cpp: In function 'int main()':
a.cpp:16:20: warning: unknown conversion type character 'l' in format [-Wformat=]
     scanf("%llu",&n);

So the compiler will ignore the extra l and scan the input as %lu. If you are compiling on a 32bit system, a long integer will most probably be 32bits long, i.e. 4 bytes.
So the number scanned will occupy 4 bytes in your memory and since the arr[n] array is a long long array, i.e. each element is 64bits - 8 bytes, only the first 4 bytes of each element will be written by scanf.
Assuming you are on a little endian system, these 4 bytes will be the least significant part of the long long element. The most significant part will not be written and will probably contain garbage. The sort algorithm though, will use the full 8 bytes of each element for the sorting and so will sort the array using the garbage in the most significant part of each element.

Since you are using code blocks on a Windows 32bit system, try replacing all occurrences of "%llu" with "%I64u".

axxis
  • 954
  • 1
  • 10
  • 18
0

There is all sorts of possible explanations. Most likely is a compiler (or library or runtime) in which scanf() doesn't properly support the %llu format with long long unsigned types.

long long types were not formally part of C before the 1999 standard, and not part of C++ before (from memory) the 2011 standard. A consequence is that, depending on age of your compiler, support varies from non-existent to partial (what you are seeing) to complete.

Practically, because of how C++ stream functions (operator>>() etc) are organised, it is arguably easier to change the C++ streaming to support a new type (like long long unsigned) than it is to change C I/O. C++ streams, by design, are more modular (operator>>() is a function overloaded for each type, so it is easier to add support for new types without breaking existing code that handles existing types). C I/O functions (like scanf()) are specified in a way that allows more monolithic implementations - which means that, to add support of new types and format specifiers, it is necessary to change/debug/verify/validate more existing code. That means it can reasonably take more effort - and therefore time - to change C I/O than C++ I/O. Naturally, YMMV in this argument - depending on skill of the library developer. But, in practice, it is a fair bet that an implementation of standard C++ streams is more modular - and therefore easier to maintain - by various measures than the C I/O functions.

Also, although you didn't ask, the construct unsigned long long int arr[n] where n is a variable is invalid C++. You are better off using a standard container, like std::vector.

Peter
  • 35,646
  • 4
  • 32
  • 74