Reading file.txt with mixture of first name, last name & middle name

I have a file below. Some have a name as input, there were a few with middle name. How should i store the names?
For the first line i can use a dummy line to store them but for the name what should i do?

1
2
3
4
Name          Age       Subject1   Subject2   Subject3
John          13        55	   55 	      55   
John Terry    15        55	   55 	      55   
John X Terry  13        55	   55 	      55   
Depending on the format of the file, you might be able to make certain guarantees.

- Is a number allowed to be a last name? Can a suffix like "3" (maybe meaning "the third") happen? If not, then parse each word, and if that word is a number, then you know the name is over, and the age has begun.

- Is there guaranteed to be a constant number of characters (including spaces) between the start of the line and the first number character (e.g. 14 as your example has)? If so, you can just read in the first 14 characters, and then strip trailing spaces from the string.

Hastily made example of first:
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
// Example program
#include <iostream>
#include <string>
#include <sstream>

// more like "is_positive_int_of_unbounded_size"
bool is_int(const std::string& token)
{
    bool nondigit_found = false;
    for (size_t i = 0; i < token.length(); i++)
    {
        if (!std::isdigit((unsigned char)token[i]))
        {
           nondigit_found = true;
           break;
        }
    }
    
    return !nondigit_found;
}

int get_int(const std::string& token)
{
    std::istringstream iss(token);
    int ret;
    iss >> ret;
    return ret;
}

int main()
{
    // replace this with an ifstream:
    std::istringstream file(
        "Name          Age       Subject1   Subject2   Subject3\n"
        "John          13        55	   55 	      57\n"
        "John Terry    15        55	   55 	      59\n");

    std::string dummy;
    if (!(file >> dummy >> dummy >> dummy >> dummy >> dummy))
    {
        std::cout << "Error opening file\n";
        return 1;
    }
    
    std::string token;
    while (file >> token)
    {
        std::string name = token; 
        
        int age = -1;
        
        while (file >> token)
        {
            if (is_int(token))
            {
                age = get_int(token);
                break;
            }
            else
            {
                name += " ";
                name += token;
            }
        }

        int subject[3] {};
        file >> subject[0] >> subject[1] >> subject[2];
        
        std::cout << name << " | " << age << " | " << subject[0] << ' ' << subject[1] << ' ' << subject[2] << '\n';
    }
}

John | 13 | 55 55 57
John Terry | 15 | 55 55 59
Last edited on
Consider:

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
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>

struct Person {
	std::string name;
	int age {};
	std::vector<int> marks;
};

std::istream& operator>>(std::istream& is, Person& p)
{
	std::string line;

	if (std::getline(is, line)) {
		std::istringstream iss(line);

		p.name.clear();
		p.marks.clear();

		for (std::string str; !(iss >> p.age); p.name += str) {
			iss.clear();
			iss >> str;

			if (!p.name.empty())
				p.name += ' ';
		}

		for (int i {}; iss >> i; p.marks.push_back(i));
	}

	return is;
}

std::ostream& operator<<(std::ostream& os, const Person& p)
{
	os << std::setw(15) << std::left << p.name << "  " << p.age << ' ';

	for (const auto& m : p.marks)
		os << ' ' << m;

	return os;
}

int main()
{
	std::ifstream ifs("names.txt");

	if (!ifs)
		return (std::cout << "Cannot open file\n"), 1;

	std::string line;

	std::getline(ifs, line);		// Remove header line

	std::vector<Person> students;

	for (Person p; ifs >> p; students.push_back(p));

	for (const auto& s : students)
		std::cout << s << '\n';
}


Given input of:


Name          Age       Subject1   Subject2   Subject3
John          13        55	   55 	      55   
John Terry    15        55	   55 	      55   
John X Terry  13        55	   55 	      55   


Displays:


John             13  55 55 55
John Terry       15  55 55 55
John X Terry     13  55 55 55

Topic archived. No new replies allowed.