0

I am having trouble parsing the input file in the Auction Problem of Facebook HackerCup.

Every line of the input file contains 9 space-separated integers: N, P1, W1, M, K, A, B, C and D. According to the input constraints the numbers can be as big as 10^18. So, I decided to use long long int to store the variables.

I am doing:

FILE *fr;
long long int N, P1, W1, M, K, A, B, C, D;
char line[1024];    
fr = fopen ("input.txt", "rt");

while(fgets(line, 1024, fr) != NULL)
{
    sscanf(line, "%lld %lld %lld %lld %lld %lld %lld %lld %lld", &N, &P1, &W1, &M, &K, &A, &B, &C, &D);
    printf("N:%lld P1:%lld W1:%lld M:%lld K:%lld A:%lld B:%lld C:%lld D:%lld\n\n", N, P1, W1, M, K, A, B, C, D);
}

For a line 81834165 9999991 1 9999991 9999989 389999650 169999844 799999121 149999837, I get N:81834165 P1:4367 W1:9999991 M:4078336 K:1 A:2292512 B:9999991 C:2292488 D:9999989

Can you please help me to point out the problem in this code? Any recommendation about parsing a similar file would also be appreciated.


Edit: I should add that it works for int variables as in:

char line[1024];    
int N, P1, W1, M, K, A, B, C, D;

strcpy(line, "81834165 9999991 1 9999991 9999989 389999650 169999844 799999121 149999837");
printf("Line: %s", line);
sscanf(line, "%d %d %d %d %d %d %d %d %d", &N, &P1, &W1, &M, &K, &A, &B, &C, &D);
printf("ret_val:%d\n\n", ret_val);
printf("N:%d P1:%d W1:%d M:%d K:%d A:%d B:%d C:%d D:%d\n\n", N, P1, W1, M, K, A, B, C, D);

I just noticed something strange. Printing more than one long long int variables in one printf() outputs wrong values while printing them in separate printf()s outputs right values. I mean:

printf("N:%lld P1:%lld\n", N, P1);
printf("N:%lld\n", N);
printf("P1:%lld\n", P1);

outputs:

N:81834165 P1:2009288239
N:81834165
P1:9999991

Do you have any idea about it?


SOLUTION

I have found out that the problem was with the compiler I was using (gcc on MinGW) On this compiler, I needed to replace %lld with %I64d. I found a similar problem at this post.


Community
  • 1
  • 1
mustafa
  • 3,605
  • 7
  • 34
  • 56
  • It's work fine for me. please send your whole code. (I just wrap it with `#include ` , `int main(){ ` and `return 0;}` I also guess that the problem is in the reading from file, so your test with `int` doesn't prove anything. – asaelr Jan 24 '12 at 14:03
  • yes, it is exactly as yours. But it doesn't work for me. Note that it works for `int` variables. – mustafa Jan 24 '12 at 14:07
  • Well, since the same code works for me, but not for you, I suggest you to run it in debugger. Also, what happens if you use `strcpy` (like your second code) with `long long int` (as your first code)? – asaelr Jan 24 '12 at 14:10
  • The `'t'` in the mode argument is not portable. – pmg Jan 24 '12 at 14:11
  • @asaelr it's the same result with `strcpy`. I will check it with a debugger. – mustafa Jan 24 '12 at 14:11
  • @pmg; the problem is not `'t'`, it works for `int` variables. And, it doesn't work even with `strcpy` for `long long int` variables – mustafa Jan 24 '12 at 14:22
  • 1
    Are you compiling with a C99 implementation? `long long` did not exist (except as an extension) in C89. Increase the level of warning of your compiler and mind the warnings. You can check for a C99 implementation with `printf("%ld", __STDC_VERSION__);` If it doesn't exist or is less than 199901 you don't have a C99 implementation. – pmg Jan 24 '12 at 14:36
  • Hi @pmg, I get ` error: '\_\_STDC_VERSION\_\_' undeclared here (not in a function)` – mustafa Jan 24 '12 at 15:20
  • can you please see the last edit I made in the question? printing multiple `long long int` in one `printf()` statement outputs wrong values – mustafa Jan 24 '12 at 15:22
  • Maybe the error is in the printf. Try printfing a long long that is larger than 4294967296. – Mr Lister Jan 24 '12 at 15:25
  • @MrLister; yes, it can't print a number bigger than `2^32=4294967296`. It can not print 2 `long long int`s smaller than that as well. Is it a problem about my compiler(gcc from MinGW)? Or, a general bug? – mustafa Jan 25 '12 at 16:23
  • Rather than use `sscanf(line, "%lld %lld %lld ...`, use `#define S64 "%I64d" sscanf(line, S64 S64 S64 ..` then code only needs to conditionally compile using `#define S64 "%I64d"` or `#define S64 "%lld"`. – chux - Reinstate Monica Jan 21 '15 at 19:54

2 Answers2

2

Apparently, %lld doesn't work correctly. According to this page, "You should use %I64d instead of %lld as MinGW uses MSVCRT."

Hope this helps!

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
0

Make sure to check the return value of sscanf(). There might be subtle errors in your input that causes it to abort after the first few conversions.

unwind
  • 391,730
  • 64
  • 469
  • 606