Importing Data from file into Struct

Jun 25, 2018 at 4:18pm
I am creating a program when ran searches through the current directory for all files ending in .csv and then imports the data into a vector. I am struggling with getting the data into variables any help would be greatly appreciated. Below is what I have so far.

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
#include <stdio.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>


using namespace std;

int main(void)
{


	struct data
	{
		string firstname;
		string lastname;
		int weight;
		int age;
	};

	vector<data> filedata(1000);


	// Pointer for directory entry
	struct dirent *de;

	// opendir() returns a pointer of DIR type. 
	DIR *dr = opendir(".");

	// opendir returns NULL if couldn't open directory
	if (dr == NULL)
	{
		cout << "Could not open current directory" << endl;
		cin.get();
		return 0;
	}

	while ((de = readdir(dr)) != NULL)
	{
		string name(de->d_name);

		// Search directory for all files ending in .csv
		if (name.size() > 4 && name.substr(name.size() - 4) == ".csv")
		{
			cout << name << ":\n";
			ifstream fin(name); //bring in file
		}
	
	}
	cin.get();
	closedir(dr);

	return 0;
}
Jun 26, 2018 at 9:10am
What exactly is your problem?

You may use getline() to read line by line.

http://www.cplusplus.com/reference/string/string/getline/?kw=getline

Then you can use stringstream in order to break the colums into it parts:

http://www.cplusplus.com/reference/sstream/stringstream/?kw=stringstream

again with getline(..., ';')
Jun 26, 2018 at 1:14pm
My problem is that when breaking it up I need to include the commas so I can store them.
Jun 26, 2018 at 1:19pm
why? The data in the struct is by column/field. You can put the commas back when you write it back out if you need to write a csv again. They are implicitly stored already.
Last edited on Jun 26, 2018 at 1:20pm
Jun 26, 2018 at 2:03pm
It appears that you are using Visual Studio; this should work with a recent version of Visual Studio.

Note: uses the regex library: https://en.cppreference.com/w/cpp/regex
and the filesystem TS: https://en.cppreference.com/w/cpp/filesystem

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
#include <iostream>
#include <fstream>
#include <filesystem>
#include <regex>
#include <string>

namespace fs = std::experimental::filesystem;

// get the names of all files in the directory with extension .csv
std::vector<std::string> csv_files( const std::string& dir_path = "." )
{
	std::vector<std::string> result;

	for( const fs::path& path : fs::directory_iterator(dir_path) )
		if( fs::is_regular_file(path) && path.extension() == ".csv" ) result.push_back( path.string() );

	return result;
}

struct data
{
	std::string first_name;
	std::string last_name;
	int weight;
	int age;
};

// extract data from the line; return true if successfully extracted
bool parse_line(const std::string& line, data& d )
{
	static const std::regex csv_re("^([^,]+)\\,([^,]+)\\,\\s*(\\d+)\\s*\\,\\s*(\\d+)\\s*$");

	std::smatch match_results;
	if( std::regex_match( line, match_results, csv_re ) )
	{
		d = { match_results[1], match_results[2], std::stoi(match_results[3] ), std::stoi(match_results[4]) };
		return true;
	}

	d = {}; // parse failed
	return false;
}

// return all data extracted from a file
std::vector<data> parse_file(const std::string& path)
{
	std::vector<data> result;

	std::ifstream file(path);
	std::string line;
	data d;
	while( std::getline(file, line) ) if( parse_line( line, d ) ) result.push_back(d);

	return result;
}

int main()
{
	for( const auto& file_name : csv_files() ) // for each .csv file in the current directory
	{
		std::cout << "\nfile name: " << file_name << "\n----------------\n";

		// print out the data extracted from the file
		for( const data& d : parse_file(file_name) )
			std::cout << d.first_name << ' ' << d.last_name << ' ' << d.weight << ' ' << d.age << '\n';
	}
    
    std::cout << "\n*** ok ***\n" ;
}

http://rextester.com/SSYRB95275
Jun 26, 2018 at 4:32pm
Thank you! and Jonnin I need so read the comma because its a validation tool and the commas must be in specific spots.
Jun 26, 2018 at 4:44pm
I get that, you need to read them (even if used as a delimiter in the reading) to get it into the struct as well. My point was, I think you may be able to avoid storing them directly as you know where they go. Not sure, but think it over.
Last edited on Jun 26, 2018 at 4:45pm
Topic archived. No new replies allowed.