Name Scrambler and Selecter

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:
}
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';
}
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
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.
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.