Unknown
Unknown

Reputation: 21

How to use scanf in for loop as a condition in c programming language

As in the following codes I did not understand usage of scanf in for loop.

How can I use or what it does when i use it?

#include<stdio.h>

int main() {

char word[10];
int count[10] = {0};

printf("Enter text:\n");

for(scanf("%s", word); word[0] != '.'; scanf("%s", word)) {
    int len;

    for(len = 0; word[len] != '\0'; len++);
        count[len]++;
}

int i;
for(i = 1; i < 10; i++) {
    printf("There are %d words with %d letters\n", count[i], i);
}

Upvotes: 0

Views: 5981

Answers (7)

Box Box Box Box
Box Box Box Box

Reputation: 5370

A for loop has three parts. The first part is always executed first, and never executed again. So doing

for(scanf("%s", word); word[0] != '.'; scanf("%s", word)) {

is basically equivalent to

scanf ("%s", word);
for(; word[0] != '.'; scanf("%s", word)) {

If you're not understanding how a for loop works, see the flowchart:

enter image description here

(Source)

If you want a tutorial, see this tutorial on loops.

Upvotes: 1

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16112

It's not that common to use complicated function calls directly in loop statements because it may impair readability. (An example for a simple function call is K&R's famous while((c = getchar()) != EOF).)

That said, I would prefer the scanf in a while loop, and test both conditions which are necessary to perform a meaningful loop action:

while( scanf("%9s", word) > 0 && word[0] != '.') {/* use word */}

The short-cutting && operator tests the second condition (here: word[0] != '.' only if the first one was true. Here word is only tested if scanf could read something.

Using the while loop makes it clear that we are testing a condition and avoids repeating the scanf expression.

About your original code:

  • The for loop wouldn't have to repeat scanf if it had the scanf in the test (which is executed before each iteration, including the first one).
  • In that case the initialization part of the for loop is empty which sometimes indicates that one could use a while loop, as I would here.
  • The scanf result is not tested in your code, which is major bad. scanf returns the number of successfully converted items, which may be zero if the input doesn't match; or a negative number for EOF and I/O errors. It is essential for a correct program to test this. In your case badly formatted input or I/O errors would probably leave word permanently unchanged; your loop condition would never be false and the program would be called in an infinite loop.
  • Lundin pointed out correctly that robust code must also make sure that scanf doesn't write beyond the bounds of word, in case the input words are longer than 9 characters. That's achieved by a maximum field length. The simple solution here does not handle such input formatting errors properly from a logical perspective (the next scanf will read the part of a too-long word left behind in the previous iteration), but is only a technical protection.

Upvotes: 0

Marievi
Marievi

Reputation: 5009

In general, a for loop has the following structure:

for (part1; part2; part3) {
    ....
}
  • Part 1 is a statement which is executed once, before the loop starts. After its execution, you get into the loop and its statements start to execute. This part is mainly used for initializations useful for the loop. If you leave it empty, you simply do not do any action before the loop.
  • Part 2 is the condition you check at each iteration.
  • Part 3 is a statement which is executed at the end of each iteration.

So here, Part 1 is the statement scanf("%s", word);, which means that initially you read a string before you get into the loop. After every iteration, you check the condition and Part 3 is again the statement scanf("%s", word);. Consequently, after every iteration you read a new string (and then use it in your condition).

Actually, this loop is equivalent to

scanf("%s", word);
while(word[0] != '.')
{
    int len;

    for(len = 0; word[len] != '\0'; len++);
        count[len]++;
    scanf("%s", word);
}

Upvotes: 2

Ash
Ash

Reputation: 186

I can understood from your for loop is that

for(scanf("%s", word); word[0] != '.'; scanf("%s", word))

you are going to input strings and count the number of words and letters untill '.' is given as the first character of the string.

Nothing wrong in this for loop, because after getting each string you are checking with the '.' and counting according to it.

May be not the proper way of coding, but can work for this situation.

Upvotes: 0

Nutan
Nutan

Reputation: 786

    for(scanf("%s", word); word[0] != '.'; scanf("%s", word)) 
    {
      int len;

      for(len = 0; word[len] != '\0'; len++);
      count[len]++;
    }

Syntax of the for loop is for(initialization;condition;increments/decrements)

  • in the code first scanf() in for loop is taking the input from the user and in word as a string

  • then the condition is getting checked whether word[0] is . or not

  • then in increment scanf() again the new string is getting read at run time

So the scanf() used in the for() loop is to read the input at run time

Upvotes: 0

Lundin
Lundin

Reputation: 215245

That's a rather ugly loop. Since the for loop is designed to allow any form of expression both in the 1st and 3rd clause, it works. That doesn't mean you should be writing code like that though.

The loop is equivalent to:

scanf("%s", word);
while(word[0] != '.')
{
  ...
  scanf("%s", word);
}

I would suggest you use while instead.

Upvotes: 1

Lincoln Cheng
Lincoln Cheng

Reputation: 2303

A usual for.. loop is as such: for(DO_ONCE_WHEN_THE_LOOP_STARTS; CONDITION_TO_CONTINUE ; DO_AT_END_OF_EACH_ITERATION) {STATEMENTS;}.

In the code above,scanf("%s",word) is executed at the start of the loop, and at the end of every iteration of the loop.

Upvotes: 0

Related Questions