Hello sarvcr,
getline(cin, frase); //<---- This line gets ignored
. Not entirely correct. It is not ignoring the line it is just eating the (\n) left in the buffer so that the next "std::getline" will work.
What you must first understand is
cin >> n;
is called formatted input. First it detects the type of variable being used, in this case an "int", and excepts a whole number to be entered. If not "std::cin" will be put in a failed state and unusable the rest of the program. So if the 1st "std::getline()" is being ignored that would be because "std::cin" has failed and is unusable. The other part of formatted input is that it leaves the (\n) in the buffer for whatever is next.
What you type on the keyboard is not put directly into a variable. It 1st goes into a buffer until you press "Enter" then it will try to put what you have typed into the variable.
The other thing with formatted input is that it will stop at the first white space, that being (space, \t, \v, \f, \r and \n) as seen at
http://www.cplusplus.com/reference/cctype/isspace/ there may be others I could not find the table I was looking for, or a (\n) whichever comes 1st. But when it stops at a (\n) it leaves this in the buffer and needs to be cleared before any "std::getline" is called.
Either of the above solutions will work. I tend to just use:
|
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
|
When I first was shown this it was said to be the most portable way to write it as any compiler and set of header files can use it.
The other side is unformatted input, the "std::getline()". Once you press "Enter" "std::getline" will store what was typed on the keyboard including any type of white space. It also reads the (\n) and discards it as it is not needed for a "std::string". This leaves you with an empty buffer for whatever is next for input.
This also applies to reading from a file.
In addition to the above 2 examples you can use:
std::cin.ignore();
. This will ignore the default 1 character or until it reaches "Trates::eof":
https://en.cppreference.com/w/cpp/io/basic_istream/ignore
The other option is:
std::cin.ignore(1000, '\n')
. It all comes down to what you will need to do.
I reworked your program and added some comments, see what you think:
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#include <iostream>
#include <limits>
#include <string>
#include <sstream>
using namespace std;
constexpr int MAXSIZE{ 40 };
class ColeccionFrase
{
private:
int cantidad{};
int size{MAXSIZE};
string frase[MAXSIZE];
public:
//ColeccionFrase(){} // <--- Can be written as this.
ColeccionFrase()
{
//cantidad = 0;
//size = 40;
//for (int i = 0; i < size; i++)
//{
// frase = "";
//}
}
//ColeccionFrase(int amtUsed) : size(amtUsed) {}
ColeccionFrase(int amtUsed)
{
//cantidad = 0;
size = amtUsed;
//for (int i = 0; i < size; i++)
//{
// frase[i] = "";
//}
}
~ColeccionFrase() // <--- Not needed because the compiler will create this for you. OK if you leave.
{
}
void agregarElemento(string elem)
{
if (cantidad <= size) // <--- Should just be (<) as "size" could be 40 which is 1 past the end of the array.
{
frase[cantidad] = elem;
cantidad = cantidad + 1; // <--- "cantidad++;" is all you need.
}
}
//To String
string toString()
{
stringstream s;
for (int i = 0; i < cantidad; i++)
{
s << i + 1 << ") " << frase[i] << '\n';
}
return s.str();
}
//Get
string getfrase(int i)
{
return frase[i];
}
//Set
void setfrase(int i, int n)
{
frase[i] = n;
}
};
int main(int argc, char *argv[]) // <--- If you are not using "argc" and "argv" they are not needed.
{
string frase; // <--- Empty when defined. Does not need initialized.
int amtUsed{}; // <--- [b][i]ALWAYS initialize all your variables.[/b]
int contador{ 1 };
cout << "Ingrese la cantidad de frases a guardar: "; //<---Amount of strings to add
cin >> amtUsed;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::cout << '\n';
//getline(cin, frase); //<---- This line gets ignored, I'm using it so the ones that matter won't. Without this line the first iteration would be lost.
//ColeccionFrase FraseA; // <--- Uses default ctor.
ColeccionFrase fraseA(amtUsed); // <--- Should be using this 1. Uses overloaded ctor.
do
{
cout << contador << ") ";
getline(cin, frase);
fraseA.agregarElemento(frase);
contador++;
} while (contador <= amtUsed);
cout << '\n' << fraseA.toString();
return 0; // <--- Not required, but makes a good break point for testing.
}
|
At the top I added some header files. DO NOT count on "sstream" including "string" this may not happen with all compilers. it is better to include what you need then if a header file includes the same header file the include guards will only let it compile once.
In your class you are doing more work in your ctors than you need to. The default ctor can be empty because you can initialize your variables when defined.
In the overloaded the only thing you need is to set the "size" variable.
The for loops in each ctor have no use. A "std::string" is empty with no size when defined and giving it a value of ("") has no effect. It is still empty with no size.
Since you have nothing special for your dtor the compiler will still provide a default dtor at compile time. Only when you define an overloaded ctor or dtor do you need to define a default ctor or dtor.
Your class function "toString()" works because it is part of the class, but keep in mind that the "string" class has a member function called "toString()" and your class function name is confusing.
I changed some of the variable names. Try to avoid using single letter variable names as they have no meaning and are hard to follow.
Using "i", "j" or "k" in a for loop is OK because these variables are local to the for loop and are destroyed when the loop ends.
Line 97 is just a replacement for line 93. Other than the ignore there ar simplier ways to eat the (\n) left in the buffer.
Including line 93 eliminates line 97.
See if any of this helps you out.
Andy