-2

How do I stop accepting input for an array when a value of -1 is entered?

This is my code for accepting input. My line of thinking is that I need to input a do while loop before the for loop, but I am not sure how to write it out.

void getdataset(int[]);


int main()
{
  int dataset[LENGTH];

  getdataset(dataset);

  return(0);
}

void getdataset(int dataset[])
{
  int lcv;

  printf("Enter up to 25 values or -1 to exit: ");
  for(lcv = 0; lcv < LENGTH; lcv ++)
  {
    scanf("%d", &dataset[lcv]);
  }
}
  • `if(dataset[lcv] == -1) break;` – iBug Jul 30 '17 at 02:17
  • `int v;..for(lcv = 0; lcv < LENGTH && scanf("%d", &v) == 1 && v != -1; lcv++) dataset[lcv] = v;` – BLUEPIXY Jul 30 '17 at 02:19
  • course standards prohibit me from using breaks for anything other than switch constructs, I tried using while and if loops, but even though the code compiles, it becomes an infinite loop – skyblade1234 Jul 30 '17 at 02:20
  • I'm curious: which course standards? A Computer Science teacher? – Alexandre Fenyo Jul 30 '17 at 02:33
  • Such information belongs into the question. With that restruiction, there is only a less clear&readable variant. – too honest for this site Jul 30 '17 at 02:55
  • yes, I am taking private classes under an instructor, and he sets some guidelines for me. I havent delved far into goto functions etc, so Im trying to make the code as simple and easy to understand. – skyblade1234 Jul 30 '17 at 02:55
  • I do not have the course standards, it comes in a book called computer science, A structured programming approach using C. there is no one page which has all the course standards – skyblade1234 Jul 30 '17 at 02:56

4 Answers4

1

I suggest following code.

#include <stdio.h>

#define LENGTH 25
#define EOI -1 //End Of Input

size_t getdataset(int array[], size_t array_size);

int main(void){
    int dataset[LENGTH];

    size_t n = getdataset(dataset, LENGTH);//Pass the size of the array

    //check print
    for(int i = 0; i < n; ++i)
        printf("%d ", dataset[i]);
    puts("");

    return 0;//You do not need parentheses.
}

size_t getdataset(int dataset[], size_t array_size){
    size_t c;//Count actual input.
    int v;

    printf("Enter up to %d values or %d to exit:\n", LENGTH, EOI);

    for(c = 0; c < array_size && scanf("%d", &v) == 1 && v != EOI; ++c)
        dataset[c] = v;//Error handling may be necessary.

    return c;//To omit the code, return the actual number of inputs.
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

break is your friend. It allows you to force exit a while loop, a for loop, or a do...while loop (but only one loop if nested) (or a switch statement).

So you may want to add this line after scanf in each loop.

if (dataset[lcv] == -1)
    break;

If you don't want to use break to break loops, then add a custom loop check.

int flag = 1;
for(lcv = 0; flag && lcv < LENGTH; lcv ++)
{
    scanf("%d", &dataset[lcv]);
    if (dataset[lcv] == -1) flag = 0;
}
iBug
  • 35,554
  • 7
  • 89
  • 134
0

break is a very good answer, but you can also use goto, that sometimes is better:

void getdataset(int dataset[])
{
  int lcv;
  printf("Enter up to 25 values or -1 to exit: ");
  for(lcv = 0; lcv < LENGTH; lcv ++)
  {
    scanf("%d", &dataset[lcv]);
    if (lcv[dataset] == -1) goto exitloop;
  }
  exitloop:;
}

In the previous example, break is better than goto.

But goto is better than break when you have nested loops, like that:

void getdataset(int dataset[])
{
  int lcv, i;
  printf("Enter up to 25 values or -1 to exit: ");
  for(lcv = 0; lcv < LENGTH; lcv ++)
  {
    for (i = 0; i < 1; i++)
    {
      scanf("%d", &dataset[lcv]);
      if (lcv[dataset] == -1) goto exitloop;
    }
  }
  exitloop:;
}
Alexandre Fenyo
  • 4,526
  • 1
  • 17
  • 24
  • `goto` has it's uisages, but this is not one of them. And if `break` is prohibited, `goto` is (hopefully) as well. At least most coding standard disallow its use, even thos allowing `break`ing loops. Anyway, your code is simply awful. – too honest for this site Jul 30 '17 at 02:56
  • You are wrong, because you simply miss that *there is no straightforward way to break out of nested loops without a goto, in C*. It is not only my opinion, this is an answer with 85 up votes on stackoverflow: https://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c Anyway, of course, you can try to avoid nesting loops, refactor your code, etc. You have commented my post as if I had said the best way to program exit conditions is goto. But I've just said that goto is a great tool **when you have nested loops**. I'm curious, can you give a better solution, with nested loops? – Alexandre Fenyo Jul 30 '17 at 03:21
  • More over, the latest FreeBSD kernel source tree contains exactly 25727 uses of `goto` in C files ! Not so bad for a simple keyword, in one of the best written Unix kernel. Should you consider that the FreeBSD kernel code is awful ? For more informations, read "Examples of good gotos in C or C++" at stackoverflow: https://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c – Alexandre Fenyo Jul 30 '17 at 03:32
  • Yes, and Apple-II basic used `gote` even more exessively. So what? Non sequitur! What you show is bad coding style, nothing else. Did you even read my comment and OPs comments at the question? – too honest for this site Jul 30 '17 at 03:41
  • It is discouraged to use `goto`. It worsens code's readability and adds difficulty to debugging. `break` is at least better. – iBug Jul 30 '17 at 04:03
  • Being sarcastic does not imply your opinion turns into facts. Giving peremptory and unsubtle assessments do not imply that anymore. This way, you can persuade that your opinion is the good one, that what you find a nice coding style is what everybody should consider a nice coding style, but to make people really understand what you mean, giving detailed explanations, examples, could do that a better way, I think. I've not found in your answers, any other good coding style way to exit from nested loops in C. I would really appreciate if you could give such an alternative with good coding style. – Alexandre Fenyo Jul 30 '17 at 04:05
  • `goto` may make sense for deeply nested loops, but certainly not for a single loop, and probably not for loops nested only one level deep. And deeply nested loops may be a sign that design needs to be rethought. – ad absurdum Jul 30 '17 at 04:12
  • @David: NO, in C, you can not have a label without a statement just after it. Then, exitloop being the latest label in the block, there is no statement after. Writing `exitloop:}` will raise *error: expected statement* at compilation time, this is why I'd written `exitloop:;}`. – Alexandre Fenyo Jul 30 '17 at 04:12
  • @AlexandreFenyo-- you are right; I missed that there were no subsequent statements.... – ad absurdum Jul 30 '17 at 04:13
  • @DavidBowling: I agree, with deeply nested loops, you are right, it makes sense. Of course, the example was here to show how to use goto to exit from a nesting loop, it was not a real example. – Alexandre Fenyo Jul 30 '17 at 04:15
  • 2
    @iBug, I would really appreciate if you could give an example of a good coding style way to exit from deeply nested loops in C? Thanks. – Alexandre Fenyo Jul 30 '17 at 04:25
  • @AlexandreFenyo `int exit_loop = 0;` then nest `for(init; cond && !exit_loop; step)` – iBug Jul 30 '17 at 06:52
0

An alternative way to do this without using breaks:

int i = 0, lcv = 0;

while (scanf("%d", i), ((i != -1) && (lcv < LENGTH)) {
    dataset[lcv++] = i;
}

This makes use of the comma operator which not too many people are familiar with: https://en.wikipedia.org/wiki/Comma_operator

or, in the for-loop form:

int i = 0;

for (int lcv = 0 ; scanf("%d", i), ((i != -1) && (lcv < LENGTH)) ; lcv++)
{
    dataset[lcv] = i;
}
NadavL
  • 390
  • 2
  • 12