Number of scanned letters in a sentence

I have a pretty simple question. (using C)

In a sentence like

In this document, there are 345 words and 6 figures

How do I scan 345 and 6 while ignoring everything in between?

I tried fscanf(FILE *pointer,"%d %d",&words,&figs);

But it only gets the first value ...

What am I doing wrong?

EDIT

I'm sorry I forgot to mention, the expression is always corrected ... In this document, there are # words and # figures

+2


a source to share


5 answers


This is because family functions scanf()

are designed to read from strings written using a function printf()

with the same format. Since this is the case, there is no need to resort to parsing and integer conversions:

const char *format = "In this document, there are %d words and %d figures";

int n = fscanf(fp, format, &words, &figs);
if (n != 2) //--- not recognized ...

      



Of course, the format should be exactly the same, at least up to the values ​​being read, so it is safer to store it in one place, following the principle of Once and Only Once, and the return code must be checked fscanf()

.

+2


a source


I think the way to do this is to combine strpbrk

with strtol

.

It would look like:



long int n;
const char *p = str;
while( (p = strpbrk(p, "-0123456789")) ) {
    n = strtol(p, &p, 0);
    handle(n);
}

      

Update:
Whichever you want it is better to use strtol(p, &p, 10)

, because in the test I just ran I found that it actually converted Testing0x100what happens if I use base16 hex

to 256, 16

.

+2


a source


The problem with your format string is that the space in the format string causes the whitespace to be ignored.

I don't think it can be done using only scanf()

if there was no second numeric value before the next linebreak, and you would also be vulnerable to arbitrary input lengths. But the combination fgets()

/ sscanf()

should do well:

int a=0, b=0;
char buf[255];
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%*[^0-9]%d%*[^0-9]%d", &a, &b);

      

If, however, you know that there are always two separate numeric values, and the input length is fixed to a reasonable length, the following should do it:

int a=0, b=0;
scanf("%*[^0-9]%d%*[^0-9]%d", &a, &b);

      

+2


a source


I don't think scanf / fscanf will do what you need in this case unless you know the exact format of the input string.

A better approach might be to parse the input string until you hit a space, period, or comma (or some other separator) and then see if only what you have is only numbers. If so, then you have a number, otherwise you have a word (assuming the sentence is well formed). Then you can store that number in an array or any other data structure you want.

However, if the sentence structure is always in exactly the same format, you can use this approach:

    int main() {
      char* buff = "In this document, there are 345 words and 6 figures";
      char extra1[5000];
      char extra2[5000];
      int a,b;
      sscanf(buff,"%[In this document, there are ]%d%[ words and ]%d", extra1, &a, extra2, &b);
      cout<<a<<" "<<b<<endl;
      return 0;
    }

      

+1


a source


You need to tokenize the string and check each word sequentially. The following code is modified from a C ++ reference , actually a C call.

/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="- This, a sample 9876 string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    if (pch[0] >= '0' && pch[0] <= '9')
    {
        // It a number
    }
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

      

+1


a source







All Articles