1

This scanf statement will read in numbers from input like 10ss as 10 - how do I rewrite it to ignore an int that's followed by other characters? If 10ss is read, it should ignore it and stop the for loop.

for (int i = 0; scanf("%d", &val)==1; i++)
novel
  • 77
  • 3
  • 10

2 Answers2

4

You can try reading the next character and analyzing it. Something along the lines of

int n;
char c;
for (int i = 0; 
     (n = scanf("%d%c", &val, &c)) == 1 || (n == 2 && isspace(c)); 
     i++)
  ...

// Include into the test whatever characters you see as acceptable after a number 

or, in an attempt to create something "fancier"

for (int i = 0; 
     scanf("%d%1[^ \n\t]", &val, (char[2]) { 0 }) == 1; 
     i++)
  ...

// Include into the `[^...]` set whatever characters you see as acceptable after a number 

But in general you will probably run into limitations of scanf rather quickly. It is a better idea to read your input as a string and parse/analyze it afterwards.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • @chux: I tried initially, but suppressed assignments are not included into the count returned by `scanf`. So, the version with `*` will return `1` even for `10ss` input, which is not what is needed in this case. – AnT stands with Russia Jan 17 '18 at 15:18
0

how do I rewrite it to ignore an int that's followed by other characters?

The robust approach is to read a line with fgets() and then parse it.

// Returns
//   1 on success
//   0 on a line that fails
//   EOF when end-of-file or input error occurs.
int read_int(int *val) {
  char buf[80];
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    return EOF;
  }
  // Use sscanf or strtol to parse.
  // sscanf is simpler, yet strtol has well defined overflow funcitonaitly
  char sentinel;  // Place to store trailing junk
  return sscanf(buf, "%d %c", val, &sentinel) == 1;
}


for (int i = 0; read_int(&val) == 1; i++)

Additional code needed to detect excessively long lines.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256