1

I have a doubt for example if i have an input like this :

5 4
1 2 3 4 5
2 3 4
2 3
1 2 3

Where the first number means the different "toys" there are to attribute to each kid which corresponds to the second number which is four and by consequence to the number of lines that represents each kid and the toys they want ...

How would i read an input like this in ansi C? With the use of strtok? or is there any other simpler way to do it?

i could do it with something like this

char line [250];
char * tok;
char *ptr = line;


while((scanf("%s",line)!= EOF){

    while ((tok = strtok(ptr, " ")) != NULL)
    {
        pseudo part
        //convert to int
        //add to array

    }

}

but is there any easier way to do this input without using tok? Thanks ...

6
  • Is the origin of ptr supposed to be riddle? Commented Mar 17, 2014 at 23:28
  • Have you read the man page for strtok? Successive calls use NULL instead of the original value. Commented Mar 17, 2014 at 23:32
  • i gave that as an example like i stated i dont want an alternative using strtok like i stated above one more time i want another way to do it ... Commented Mar 17, 2014 at 23:35
  • scanf("%s", line) isn't going to read a line, it's going to read a whitespace delimited string, so you don't need strtok. Commented Mar 18, 2014 at 0:02
  • if you at least read how the input works you would understand why the use of strtok.... Commented Mar 18, 2014 at 0:14

2 Answers 2

1

Recommend a classic fgets()/sscanf() combination.

Read in one line at a time. Good error checking available. Use "%n" to know where to begin the next scanning for the next toy.

char buffer[250];
if (fgets(buffer, sizeof buffer, stdin) == NULL)
  HandleEOF();
int toys, kids;
int cnt = sscanf(buffer, "%d%d", &toys, &kids);
if (cnt != 2 || toys <= 0 || kids <= 0)
  Handle_BadToysKids(cnt);
int kid_wants[kids][toys] = { 0 };

for (int k = 0; k < kids; k++) {
  if (fgets(buffer, sizeof buffer, stdin) == NULL)
    HandleEOF();
  char *p = buffer;
  int want;
  int n;
  while ((cnt = sscanf(p, "%d %n", &want, &n)) == 1) {
    if (want <= 0 || want > toys)
      Handle_BadWant(want);
    kid_wants[k][want - 1] = 1;
    p += n;
  }
}

Improvements:
Use size_t toys, kids and "%zu".
Use sentinel to check for extra junk on a line:
int ch; int cnt = sscanf(buffer, "%d%d %c", &toys, &kids, &ch);
Check *p at end of while loop - it should be '\0'.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use fgets to read a line, not scanf. scanf will read only till the first white space. (better to use fgets just because it is safer than gets)

like this:

ptr = fgets(line,sizeof(line),stdin);

Your strtok will work, if you set ptr to NULL after the first call. Anyway, it is better to add more white spaces like: " \r\n\t"

//assume ptr = line had been set by fgets...
char* tok;
do{
   const char* whitespaces = " \r\n\t";
   tok = strtok(ptr, whitespaces);
   ptr = NULL;//till next fgets
   if(tok){
      //got more number  
   }
}while(tok);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.