-1

When I give the first input, an extra 0 appears before gets() works. But if I remove gets(), then there is no problem. printf() can't be used because it breaks on blank space. Please give any alternative solution or what should I do?

 #include <cstdio>
 #include <iostream>
 #include <stdlib.h>
 using namespace std;
 int main()
 {
  long long a,i,t,count;
  int op;
  char s[10000];
  scanf("%lld",&t);
  for(i=1;i<=t;i++)
  {
    gets(s);
    a=atoll(&s[7]);
    printf("%lld",a);
  }
  return 0;
 }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Kaidul
  • 15,409
  • 15
  • 81
  • 150
  • 6
    Never use `gets()`. Never. – Greg Hewgill Apr 13 '12 at 06:15
  • @GregHewgill As soon as I saw this Qn, I was waiting for your "Never use gets(). Never" statement and it came :) – Pavan Manjunath Apr 13 '12 at 06:19
  • A reliable input function can be found at http://stackoverflow.com/questions/4023895/how-to-read-string-entered-by-user-in-c/4023921#4023921 - please, if you value your sanity or that of those that have to maintain your code, use something like that rather than gets. – paxdiablo Apr 13 '12 at 06:22
  • That's not C; or, more accurately, the headers `` and `` are not C headers but are C++ headers. That code doesn't need `` at all and should be using ``. And `using namespace std;` is definitely pure C++. – Jonathan Leffler Apr 13 '12 at 06:50
  • What is the problem "`printf()` can't be used because it breaks on blank space"? You can't use `printf()` for input, of course; did you mean `scanf()`? You should also be testing the return from `gets()` (or, rather, `fgets()`) to stop the loop on EOF. As it is, you'll have to interrupt the program if you get bored before the loop is done. The program you've written will generate zeroes for any line that doesn't contain with white space followed by an integer starting at the eighth character on the line (`&s[7]`). – Jonathan Leffler Apr 13 '12 at 07:06

4 Answers4

3

The scanf() leaves the end-of-line character of the first line in the input stream which is then consumed by gets(). This is a common beginner's error often discussed here.

Recommendations:

  1. Do not mix scanf() routines with gets() routines.
  2. Except for short test programs do not use gets() (instead use fgets()) because with gets() buffer overflows may occur.
ktf
  • 6,865
  • 1
  • 13
  • 6
  • Do not use `gets()` ever; not even for short test programs. Forget that it exists in the library. Better, replace it in the library with the implementation: `char *gets(char *buffer) { abort(); }`. But you're right about `scanf()` leaving the newline, triggering the stray `0`. – Jonathan Leffler Apr 13 '12 at 06:54
  • In addition to its other problems, `gets` was deprecated in C99, and is gone from C11. – John Bode Apr 13 '12 at 11:25
  • @JohnBode: Agreed, but sadly, `gets()` will be in the (non-standard) libraries for the next decade and more as a backwards compatibility measure. – Jonathan Leffler Apr 13 '12 at 15:35
  • @JonathanLeffler: Oh, yeah, and it's lurking in several decades' worth of legacy code as well. Just pointing out that, going forward, it's not even *defined* by the language anymore. – John Bode Apr 13 '12 at 15:45
2

You can try adding the '\n' character when you are reading with scanf:

 scanf("%lld\n",&t);
  for(i=1;i<=t;i++)
  {
    gets(s);
    a=atoll(&s[7]);
    printf("%lld",a);
  }
gabitzish
  • 9,535
  • 7
  • 44
  • 65
2

Why not:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    long long i;
    long long t;
    char s[10000];

    if (fgets(s, sizeof(s), stdin) == 0)
        return 0;
    t = atoll(s);
    for (i = 1; i <= t; i++)
    {
        if (fgets(s, sizeof(s), stdin) == 0)
            break;
        a = atoll(&s[7]);
        printf("%lld\n", a);
    }
    return 0;
}

Amongst other merits, it doesn't:

  • print stray zeroes,
  • include C++ code in a purportedly C program,
  • contain any stray (unused) variables,
  • use the dangerous gets() function.

It is fair to note a couple of deficiencies:

  • It would produce bogus output if a data line was not at least 8 characters long; it should check strlen(s) before calling atoll(&s[7])
  • We'll assume that 10K is longer than any single line it will be given to read so truncated lines won't be a problem, though JSON data sometimes seems to get encoded in files without any newlines and can be humongously long (Firefox bookmark lists or backups, for example, don't even contain a single newline).
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

I'm sure what you're trying to do here, or what the problem is. But ...

  1. As Greg Hewgill correctly said: NEVER use "gets()". It's a buffer overflow waiting to happen.

  2. You CAN use "fgets()" - and it could easily solve the problem.

  3. While you're at it, why the "scanf()", followed by "gets()", followed by "atoll()"? Can any of these inputs be merged? Or made more consistent?

  4. Where are you checking for a valid conversion from "atoll()"? Why not just use "sscanf()" (and check the return value)?

paulsm4
  • 114,292
  • 17
  • 138
  • 190