Struct variables and arrays

Hi,

I'm working with structs, and I'm trying to make an array to hold the data and cout it, but I'm not doing something correctly. I have no experience with structs and I honestly have no idea what could be wrong here. Would someone point me at the problem please?

It is homework, but it's an effort grade. I just need to understand.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>

using namespace std;

struct Frog{
  
   string Name;
   int Age;
   int LegLength;

};

const int MAX_SIZE = 20;

//void printFrog(Frog f);

int main() {

   Frog Frogs[MAX_SIZE];
   int x;
   cout << "How many frogs do you want?" << endl;
   cin >> x;
   
   for (int i = 0; i < x; i++){
      
      cout << "What is the name of Frog " << i+1 << "?" << endl;
      getline(cin, Frogs[i].Name);      
      cout << "What is the age of Frog " << i+1 <<"?" <<  endl;
      cin >> Frogs[i].Age;
      cout << "What is the leg length of Frog " << i+1 <<"?" <<  endl;
      cin >> Frogs[i].LegLength;
   
   }
   
   cout << "Frog Data:" << endl;
   
   for (int i = 0; i < x; i++){
   
      cout << Frogs[i].Name << endl;
      cout << Frogs[i].Age << endl;
      cout << Frogs[i].LegLength << endl;
   
   }
   
   return 0;

}
Last edited on
I'm not doing something correctly

No, you are doing some things correctly, just not everything. :-)
When you read the LegLength with cin >> you are leaving the newline behind in the input buffer, so the next getline(cin,...) will read an empty line.
Try adding this after the cin >> Frogs[i].LegLength;
 
cin.ignore(9999, '\n');

http://www.cplusplus.com/reference/istream/istream/ignore/
Ahhhh. That's right. I forget very easily you have to be very careful with getlines and extraction operators in conjunction.

Just to further help me understand that madness, would the get() function for eating up a single char be useful in such a situation too? Or is that for different situations?
This is one of the primary beefs I have with C++ I/O learning. No one ever teaches people past this.

IMHO, user input should always be to a std::string, via std::getline(), and then attempt to validate/convert to the desired value.

I use a fairly simple helper function/function family:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <sstream>
#include <stdexcept>
#include <string>

template <typename T>
T string_to( const std::string& s )
{
  T result;
  std::istringstream ss( s );
  ss >> result >> std::ws;
  if (!ss.eof()) throw std::runtime_error( "string_to" );
  return result;
}

To make life even easier, a simple function to work like getline is also useful:

1
2
3
4
5
6
7
8
template <typename T>
std::istream& readline( std::istream& ins, T& value )
{
  std::string s;
  if (getline( ins, s )) 
    value = string_to <T> ( s );
  return ins;
}

Now you can write code that will always accept user input correctly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
try
{
  Frog frogs[MAX_SIZE];
  int nfrogs;
  cout << "How many frogs do you want?" << endl;
  readline( cin, nfrogs );

  for (int i = 0; i < nfrogs; i++)
  {
    cout << "What is the name of Frog " << (i+1) << "? ";
    readline( cin, frogs[i].Name );

    cout << "What is the age of Frog " << (i+1) << "? ";
    readline( cin, frogs[i].Age );

    cout << "What is the length of Frog " << (i+1) << "? ";
    readline( cin, frogs[i].LegLength );
  }

  // and so on...
}
catch (...)
{
  cerr << "Aaaiiiiiiiiiii!\n";
  return 1;
}

Hope this helps.
Last edited on
Yes it does. I had to think about that for a minute since I've never used std::, but it made sense eventually.

Thank you.
Topic archived. No new replies allowed.