1

I'm attempting to read in user inputted values about put them into a string class array, but I'm getting a BAD EXCESS error, I'm guessing its something really simple that I'm doing wrong. Here is what I got. Any help would be great

int main()
{
   const int SIZE = 5;
   string fruity[SIZE];
   int i;

   cout << "Enter the names of five kinds of fruit:" << endl;
   for(i = 0; i < SIZE; i++)
   {
      cout << "Enter Name of Fruit" << endl;
      getline(cin, fruity[i]);
   }

   cout << fruity[i] << endl;

   return 0;
}
iammilind
  • 68,093
  • 33
  • 169
  • 336
hart929
  • 35
  • 2
  • 8

5 Answers5

4
cout << fruity[i] << endl;

This is invalid. Do this instead:

for(i = 0; i < SIZE; i++)
     cout << fruity[i] << endl; 

Because at that point your i will be equal to SIZE, and fruity[SIZE] is invalid.

  • so is the `fruity` array now populated with the user inputted values? – hart929 Sep 20 '11 at 05:21
  • `fruity[0]` should be `fruity[i]`?? – Alok Save Sep 20 '11 at 05:21
  • Als, yes, a typo. jooMLA, yes yes it is. In the loop, you don't create a temporary variable but use an existing one, therefore after the loop i = SIZE, and you cannot fruity[size], so you need another loop. – Laurynas Tretjakovas Sep 20 '11 at 05:24
  • @LaurynasTretjakovas - would there be a more efficient way to do it, so that I didn't have to use `i` ? Somehow I could just use `SIZE` ? it all seems kind of sloppy and yes I'm new to this. – hart929 Sep 20 '11 at 05:27
  • You mean: `cout << fruity[i] << endl;`. Use `@muntoo` to notify me once you're done so you can get the upvote. – Mateen Ulhaq Sep 20 '11 at 05:27
  • @jooMLA there is. Delete the i variable then change the loops from for(i = 0; i < SIZE; i++) to for(int i = 0; i < SIZE; i++) - notice the int in the beginning, a temporary variable will be created and you won't have to declare it in main. – Laurynas Tretjakovas Sep 20 '11 at 05:35
2

After the for loop, the variable i has the value SIZE and so when you try to access it you go out of bounds. You will have to use another loop if you want to output it like so:

for (i = 0; i < SIZE; i++) {
    cout << fruity[i] << endl;
}
flight
  • 7,162
  • 4
  • 24
  • 31
  • `i` is declared outside the `for` loop. – Alok Save Sep 20 '11 at 05:20
  • Eugh. What happened there. Edited to fix the real problem. – flight Sep 20 '11 at 05:23
  • so is the array now populated by the inputs? so if I wanted to send it to a selection sort I could? – hart929 Sep 20 '11 at 05:25
  • What happened? What happened is, Your previous answer was wrong and that was what my comment pointed out. Then you edited the answer and cameback to ask What happened? Really? – Alok Save Sep 20 '11 at 05:26
  • @jooMLA Yes. You populated it with input in the previous `for` loop. – flight Sep 20 '11 at 05:26
  • @Als What? I'm just saying "Oops. I made a mistake but I've seen the problem now so I'll edit my answer so it's still useful" – flight Sep 20 '11 at 05:27
  • @quasiverse - Thx. What would be the arguments for the function? `function(string fruit[], int SIZE)` ? – hart929 Sep 20 '11 at 05:32
  • @jooMLA Yes. That would be correct although many others here would strongly prefer that you use something like a `vector`. – flight Sep 20 '11 at 05:32
1

In the following statement

cout << fruity[i] << endl;

"i" is out of range. The value of "i", when exiting the for loop "5" And your compiler should have warned you about using "i" outside the scope of the for-loop. Your for-loop sets fruity[0], fruity[1], fruity[2], fruity[3], fruity[4], but "fruity[5]" is out of range. Hence, garbage data when you try to print "fruity[i]". This leads to a seg fault crash.

selbie
  • 100,020
  • 15
  • 103
  • 173
1

Always make variables as local as possible. C++ allows you to define loop variables within the loop

 for(int i = 0; i < SIZE; i++)
 {
   ...
 }
 // i no longer in scope

so that they fall out of scope at the end of the loop, which is as local as it gets.

Doing this will reveal that you are currently using i for accessing the array after the loop, at which point i has the value SIZE, resulting in an access out of bounds. (Remember, arrays have the indexes 0..SIZE-1.)

I have no idea what the final line in your program

cout << fruity[i] << endl;

is supposed to do, but if you want to output the array's conetent (as other answers suggest), you will indeed need another loop.

Other, more minor points:

  1. We don't really know what string class you are using, because you omitted the std:: prefix. (The same goes for all the other identifiers from the std library you are using.) I disapprove of that.

  2. The correct type for array indexes is std::size_t.

  3. The std::endl manipulator will insert a '\n' into an output stream and flush the stream's buffer. In an interactive console program as yours is this usually doesn't do any harm. Remember it, though, as flushing the buffer prematurely might considerably slow down a program. (I have seen a case were a program writing a lot of data into a file stream in trickles of a couple of bytes was slowed down by an order of magnitude due to this.) In your case, flushing the output stream#s buffer manually is never really necessary. (Of course, you do want your prompts to appear before you read from the input stream, but this is achieved by std::cout being tied to std::cin by default, making std::cout flush whenever the program attempts to read from std::cin.)

The program, as I would write it, would look like this:

// Beware, brain-compiled code ahead!
#include <string>
#include <iostream>

int main()
{
   const std::size_t size = 5;
   std::string fruity[size];

   std::cout << "Enter the names of five kinds of fruit:" << '\n';
   for(std::size_t i = 0; i < size; ++i)
   {
      std::cout << "Enter Name of Fruit" << '\n';
      std::getline(std::cin, fruity[i]);
   }

   for(std::size_t i = 0; i < size; ++i)
   {
     std::cout << fruity[i] << `\n`;
   }

   return 0;
}
Community
  • 1
  • 1
sbi
  • 219,715
  • 46
  • 258
  • 445
0

You need a loop:

for(int i = 0; i < SIZE; i++)
{
   cout << fruity[i] << endl;
}
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132