Reading csv file

Feb 26, 2019 at 12:18pm
I have a csv file like this

1
2
3
4
5
6
7
8
9
10
11
No,Student ID,Last name,First name,Gender,DoB
1,18127221,Nguyen Van,Tuan,Male,4/11/2000
2,18127222,Tran Van,A,Female,9/6/2000
3,18127223,Le Nguyen,Ngoc,Female,8/1/2000
4,18127224,Donald,Trump,Male,12/5/2000
5,18127225,Mike,Pence,Male,21/4/2000
6,18127226,Nguyen Xuan,Phuc,Male,2/9/2000
7,18127227,Nguyen Phu ,Trong,Male,12/12/2000
8,18127228,Pham Binh,Minh,Male,13/3/2000
9,18127229,Vu Duc,Dam,Male,3/2/2000
10,18127230,To ,Lam,Male,4/6/2000


To read this file, I wrote a program:

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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Student
{
	int no, id, day, month, year;
	string last_name, first_name, gender, No, student_id, Last_name, First_name, Gender, DoB;
	char hashtag, comma;
};
int main()
{
	ifstream in;
	in.open("E:\students.csv");
	Student student;
	if (in.is_open())
	{
		cout << "Error!\n";
	}
	else
	{
		in >> student.No >> student.student_id;
		getline(in, student.Last_name);
		getline(in, student.First_name);
		in >> student.Gender >> student.DoB;
		while (!in.eof())
		{
			in >> student.no >> student.id;
			getline(in, student.last_name);
			getline(in, student.first_name);
			in >> student.gender >> student.day >> student.hashtag >> student.month >> student.hashtag >> student.year;
		}
		in.close();
	}
	ofstream out;
	out.open("E:\student.txt");
	if (out.is_open())
	{
		cout << "Error!\n";
	}
	else
	{
		out << student.No << " " << student.student_id << " " << student.Last_name << " " << student.First_name << " " << student.Gender << " " << student.DoB << endl;
		while (!out.eof())
		{
			out << student.no << " " << student.id << " " << student.last_name << " " << student.first_name << " " << student.gender << " " << student.day << student.hashtag << student.month << student.hashtag << student.year << endl;
		}
		out.close();
	}
}

This program will read the csv and write all of the content into a txt file. However, when I compiled it and open the txt, the only thing I could see is blank, nothing in the file.
What did I go wrong?
Last edited on Feb 26, 2019 at 12:19pm
Feb 26, 2019 at 12:31pm
Backslash (\) in string literals have special meaning. If you want the file path to contain a backslash you have write two in a row.

 
out.open("E:\\student.txt");

https://en.cppreference.com/w/cpp/language/escape


Alternatively, you can use forward slashes (/) instead. It's the default on most systems and is supported on Windows as well.

 
out.open("E:/student.txt");
Last edited on Feb 26, 2019 at 12:32pm
Feb 26, 2019 at 12:39pm
Besides the problem with the backslash take a look at line 16 and 37: When the files are successfully opened you will print an error.

By the way:

Currently your read only a single dataset, the last one. An array or vector is required here.

You will write the last dataset until the stream tells eof? When will that happen? You need to write the aforementioned container.
Last edited on Feb 26, 2019 at 12:43pm
Feb 26, 2019 at 1:02pm
I got my code edited:
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Student
{
	int no, id, day, month, year;
	string last_name, first_name, gender;
	char hashtag;
};
int main()
{
	ifstream in;
	in.open("E:/students.csv");
	Student student[100];
	string  No, student_id, Last_name, First_name, Gender, DoB;
	if (! in.is_open())
	{
		cout << "Error!\n";
	}
	else
	{
		in >> No >> student_id;
		getline(in, Last_name);
		getline(in, First_name);
		in >> Gender >> DoB;
		for (int i = 0; i < 10; i++)
		{
			in >> student[i].no >> student[i].id;
			getline(in, student[i].last_name);
			getline(in, student[i].first_name);
			in >> student[i].gender >> student[i].day >> student[i].hashtag >> student[i].month >> student[i].hashtag >> student[i].year;
		}
		in.close();
	}
	ofstream out;
	out.open("E:/student.txt");
	if (! out.is_open())
	{
		cout << "Error!\n";
	}
	else
	{
		out << No << " " << student_id << " " << Last_name << " " << First_name << " " << Gender << " " << DoB << endl;
		for (int i = 0; i < 10; i++)
		{
			out << student[i].no << " " << student[i].id << " " << student[i].last_name << " " << student[i].first_name << " " << student[i].gender << " " << student[i].day << student[i].hashtag << student[i].month << student[i].hashtag << student[i].year << endl;
		}
		out.close();
	}
	system("pause");
}

But now the output is horrible:
1
2
3
4
5
6
7
8
9
10
11
No,Student ID,Last  name,First name,Gender,DoB 1,18127221,Nguyen Van,Tuan,Male,4/11/2000 2,18127222,Tran Van,A,Female,9/6/2000
3 0    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460
-858993460 -858993460    -858993460Ì-858993460Ì-858993460

What happened to the integers?
Feb 26, 2019 at 1:46pm
in >> No reads "1,18127221".

>> student_id reads "ID,Last".

getline(in, Last_name) reads " name,First name,Gender,DoB".

getline(in, First_name) reads "1,18127221,Nguyen Van,Tuan,Male,4/11/2000"

...
Last edited on Feb 26, 2019 at 1:47pm
Feb 27, 2019 at 9:07am
So I should use:
1
2
getline(in, No, ',');
getline(in, Last_name, ',');

Right?
Feb 27, 2019 at 9:51am
Yes, that looks like it should work, except for the last field where you will have to use '\n' instead of ','.
Feb 27, 2019 at 12:15pm
1,18127221,Nguyen Van,Tuan,Male,4/11/2000
As I see, I can't use getline to read the integer.
How to read the numbers while there is a comma behind them?
Feb 27, 2019 at 12:32pm
You can read the numbers as a string up to the comma and store the string value into a dummy string. After that, you can convert the dummy string into an integer using std::stoi (string to int).

1
2
3
std::string dummyString;
getline(in, dummyString, ',');
No = std::stoi(dummyString);
Feb 27, 2019 at 12:50pm
Hooray the result is great!
Thanks all for your help!
Good days!
Topic archived. No new replies allowed.