Name Scrambler and Selecter
Apr 14, 2016 at 1:04pm UTC
I am doing a side project for a class, and what I want to do is read a random name using
getline()
, then put that name into a new text file, then choose a random name from the second text file.
I thought a good way to do this would be read from the first file, store it into the second, then replace the name in the first file with a blank line, or
\n
.
I can't figure out how to replace the name in the first file so that it doesn't repeat names on the second.
Here's the current code.
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
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <ctime>
int main()
{
std::string name;
int name_num=0;
std::ofstream newfile;
std::ifstream file;
std::ofstream rewrite;
std::string newline = "\n" ;
int * store;
int second_name;
working:
file.open("Names.ycl" );
while (!file.eof())
{
getline(std::cin, name);
if (file.eof())
{
break ;
}
name_num += 1;
//This counts the number of names in the list
}
file.close();
store = new int [name_num];
second_name = name_num;
for (int c = 0; c < name_num; c++)
{
//goto finish
}
srand(time(NULL) + (time(NULL) / 2));
int name_choice = (rand() % name_num);
newfile.open("ScrambledNames.ycl" );
file.open("Names.ycl" );
while (!file.eof())
{
getline(std::cin, name);
if (file.eof())
{
break ;
}
if (name_choice == name_num)
{
newfile << name << "\n" ;
name_num = 0;
name_choice = 0;
}
}
file.close();
newfile.close();
finish:
}
Apr 14, 2016 at 1:47pm UTC
Rather strange requirements. In general, you need to read in the file, modify what you want, and then rewrite the entire file when you update a file.
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
// caveat: untested
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> readFile(const std::string& name)
{
std::vector<std::string> result;
std::string line;
std::ifstream in(name);
while (getline(in, line))
result.push_back(line);
return result;
}
void updateFile(const std::string& name, const std::vector<std::string>& names)
{
std::ofstream out(name);
for (auto & n : names)
out << n << '\n' ;
}
void appendToFile(const std::string& fname, const std::string & name)
{
std::ofstream out(fname, std::ios::app);
out << name << '\n' ;
}
std::vector<std::string>::iterator getRandomElement(std::vector<std::string>& v)
{
return v.begin() + rand() % v.size();
}
std::string removeRandomElement(std::vector<std::string> & v)
{
auto it = getRandomElement(v);
auto result = std::move(*it);
v.erase(it);
return result;
}
int main()
{
std::srand(std::time(0));
const std::string sourceFile = "Names.ycl" ;
const std::string targetFile = "ScrambledNames.ycl" ;
auto names = readFile(sourceFile);
appendToFile(targetFile, removeRandomElement(names));
updateFile(sourceFile, names);
names.clear();
names = readFile(targetFile);
auto randomName = *getRandomElement(names);
std::cout << randomName << '\n' ;
}
Apr 14, 2016 at 2:47pm UTC
Running your code, I got a compile error, integer division by zero.
This was the cause:
1 2 3 4
std::vector<std::string>::iterator getRandomElement(std::vector<std::string>& v)
{
return v.begin() + rand() % v.size();
}
Last edited on Apr 14, 2016 at 2:48pm UTC
Apr 14, 2016 at 2:52pm UTC
Running your code, I got a compile error, integer division by zero.
That's not a compile error. This would happen if
v had size 0, and
v would have size 0 if
readFile failed to read from the file.
Apr 14, 2016 at 4:39pm UTC
Ah, forgot about that.
It works perfectly, now that I've added the files being read and written to.
Thanks!
Topic archived. No new replies allowed.