C ++ adding carriage return at the beginning of a line when reading a file
I have two questions:
1) Why is my code adding a carriage return at the beginning of the selected_line?
2) Do you think the algorithm I'm using to return a random string from a file is good enough and won't cause any problems?
Example file:
line
number one
#
line number two
My code:
int main()
{
srand(time(0));
ifstream read("myfile.dat");
string line;
string selected_line;
int nlines = 0;
while(getline(read, line, '#')) {
if((rand() % ++nlines) == 0)
selected_line = line;
}
// this is adding a \n at the beginning of the string
cout << selected_line << endl;
}
EDIT: Okay, what some of you suggest makes a lot of sense. The string probably reads "\ nmystring". So I guess my question now is, how do I remove the first \ n from a string?
What you might want is something like this:
std::vector<std::string> allParagraphs;
std::string currentParagraph;
while (std::getline(read, line)) {
if (line == "#") { // modify this condition, if needed
// paragraph ended, store to vector
allParagraphs.push_back(currentParagraph);
currentParagraph = "";
else {
// paragraph continues...
if (!currentParagraph.empty()) {
currentParagraph += "\n";
}
currentParagraph += line;
}
}
// store the last paragraph, as well
// (in case it was not terminated by #)
if (!currentParagraph.empty()) {
allParagraphs.push_back(currentParagraph);
}
// this is not extremely random, but will get you started
size_t selectedIndex = rand() % allParagraphs.size();
std::string selectedParagraph = allParagraphs[selectedIndex];
For better randomness, you can choose instead:
size_t selectedIndex
= rand() / (double) (RAND_MAX + 1) * allParagraphs.size();
This is because the least significant bits returned rand()
do not behave as randomly.
a source to share
Your "random" choice is completely wrong. In fact, it will always select the first row:
rand() % 1
always 0.
There is no way to evenly select a random row without knowing the number of rows present.
Also, why are you using # as separator? By default, Getline gets a string (ending with \ n).
a source to share
New lines can be displayed from the second line you type. This is because the function getline
stops when the character is viewed #
and resumes the next time it is called from where it is to the left of the character passed through #
, which according to your input file is a newline. Read C FAQ 13.16 for effective use rand()
.
One suggestion is to read the entire file in one go, store the lines in vector
, and then output them as needed.
a source to share
1) You are not adding \n
to selected_line
. Instead, by specifying '#'
, you are simply not removing the extra characters \n
in your file. Note that your file looks something like this:
linen number one \ n # \ P line number two \ n <\ preliminarily>
So line number two is actually "\ nline number two \ n".
2) No. If you want to randomly select a line, you need to first determine the number of lines in your file.
a source to share
You can use the substr method of the std :: string class to remove the \ n after you decide which string to use:
if ( line.substr(0,1) == "\n" ) { line = line.substr(1); }
As others have said, if you want to select lines with uniform randomness, you will need to read all lines first, and then select the line number. You can also use if (rand ()% (++ nlines + 1)), which will select row 1 with probability 1/2, row 2 with probability 1/2 * 1/3, etc.
a source to share