-1

I want the cycle to end when "0 00 00" is typed by the user. Here's the code:

main()
{
    int i, o[128], m[256], s[256];
    for(i = 0; o[i] != 0 && m[i] != 00 && s[i] != 00; i++)
        scanf("%d %d %d", &o[i], &m[i], &s[i]);
    printf("ok\n");
}

but the only way for it to end is by typing some characters.

m4mmt
  • 33
  • 1
  • 6

4 Answers4

3

You have to understand sequencing of operations in the for loop to figure out the answer:

  1. The initialization operation is performed, i.e. i=0
  2. The condition is checked prior to entering the loop. Here is your first problem, becaise o[], m[], and s[] are not initialized.
  3. Loop body is executed
  4. i++ is performed
  5. The control is passed to step 2

Note that the condition in step 2 is always "ahead" of the loop body, checking elements that have not been initialized yet.

In situations like this it is better to end the loop from inside with a break statement, like this:

for (int i = 0 ; i != 128 ; i++) { // Preserve the boundaries of o[128]
    scanf("%d %d %d", &o[i], &m[i], &s[i]);
    if (o[i] == 0 && m[i] == 0 && s[i] == 0) {
        break;
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • The problem is, in our course we can't use some statements like break or switch. Can you suggest me a way to store a number sequences in the arrays until "0 00 00" is met? – m4mmt Nov 25 '17 at 11:21
  • @user8852293 You can't detect the difference between end-user entering zero and two zeros, but you can detect `0 0 0` – Sergey Kalinichenko Nov 25 '17 at 11:27
  • I tried with a do-while and with single zeros https://pastebin.com/4cAFanuB but the result is the same – m4mmt Nov 25 '17 at 11:48
2

Your code has several some problems:

  • A for loop checks its condition before executing its body. In the first round you will check uninitialized variables. Use a do ... while() loop instead or initialize your arrays.
  • You cannot parse the input as integer and the check for double zeros. If you want to do this, you have to parse this part of the input as string.
  • You should check the return value of scanf to detect errors.
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
mschmidt
  • 2,740
  • 4
  • 17
  • 31
  • The purpose of the cycle is to store the numbers in the array until the 0 00 00 sequence is met, how can I do it? – m4mmt Nov 25 '17 at 11:19
1

As is currently written, i is incremented before the condition is checked, so every time you're just checking for indeterminate values, which exhibits undefined behavior.

Use a do-while to ensure that the loop is executed at least once, while giving you more control:

i = -1; // Note the -1 here!
do{
    i++;
    scanf("%d %d %d", &o[i], &m[i], &s[i]);
} while (o[i] != 0 && m[i] != 0 && s[i] != 0);
iBug
  • 35,554
  • 7
  • 89
  • 134
0

In case you are focred to use a for-loop and to rely on its condition to break it, you might solve this issue like this:

int main(void)
{
  int o[128 + 1] = {-1}, m[256 + 1] = {-1}, s[256 + 1] = {-1};

  for(size_t i = 1; /* Use size_t to index arrays */
    i < (128 + 1) && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0; 
    i++) {
    scanf("%d %d %d", &o[i], &m[i], &s[i]);
  }

  puts("ok");
}

Please note the values at the arrays' position 0 are not read, but nailed down to -1.

If your code relies on 0-based indexing you could trick this the following way:

int main(void)
{
  int oa[128 + 1] = {-1}, ma[256 + 1] = {-1}, sa[256 + 1] = {-1};
  int *o = oa + 1, *m = ma + 1, *s = sa + 1;

  for(size_t i = 0; /* Use size_t to index arrays */
    i < 128 && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0; 
    i++) {
    scanf("%d %d %d", &o[i], &m[i], &s[i]);
  }

  puts("ok");
}

A much nicer solution however would be:

int main(void)
{
  int o[128], m[256], s[256];

  {
    ssize_t i = -1; /* If ssize_t isn't available use any signed integer wide enough. */
    do {
      ++i;
      scanf("%d %d %d", &o[i], &m[i], &s[i]);
    } while (i < 128 && o[i] != 0 && m[i] != 0 && s[i]);
  }

  puts("ok");
}
alk
  • 69,737
  • 10
  • 105
  • 255