read file fstream

i have a file *.csv. CSV is like excel format
the first line is the number of element
lines after is customer info (include: name(string), sex(bool 1/0), ID(string), address(string))

for example:
--------------------------------
2 | | |
John | 0 | 1234 | 12 a street
Mary | 1 | 4321 | 10 b street
--------------------------------

but when we read file csv, it like this
-------------------------------
2,,
John,0,1234,12 a street
Mary,1,4321,10 b street
-------------------------------
now im using fstream to read this file
what should i do?

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
#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef struct CUS
{
string Name;
bool sex;
string ID;
string Address;
};
int main()
{
int nCus;
vector<CUS*> list;
fstream fi;
fi.open("input.csv",ios::in);
if (!fi) 
{
return;
}

fi >> nCus;
for (int i = 0; i < nCus; i++)
{
CUS p = new CUS;
// Read file here
//
//
//
//
list.push_back(p);
}
return 0;
}


SO help, im stuck for 2 days
Last edited on
1. Read a line from file - use getline() maybe?
2. Use strtok() function to break the line into words using comma as delimeter/separator
3. Assign each corresponding token/word resulting from line breaking at step 2
4. Repeat steps 1-3 until no more lines found in the file

Example:

1
2
3
4
5
6
7
8
9
10
11
12

fi.getline(line, 256);
while(has more lines) {
      name      = strtok(line, ",");
      sex          = strtok(NULL, ",");
      id            = strtok(NULL, ",");
      address   = strtok(NULL, ",");
    
     //read next line
      fi.getline(line, 256);
}


Note: This is just a pseudo-code and not a real code. Just get the idea.
Last edited on
thks
but the first line is 2,,

how to?

1
2
3
4
5
6
7
8
9
10
11
12
13

fi.getline(line, 256); //get the line with the count of valid lines
strcount = strtok(line, ","); //get the first token of the first line which is 2
count = atoi(strcount); //convert string "2" to int 2;

for (i = 0; i < count; i++) {
       fi.getline(line, 256); //get valid line

      name      = strtok(line, ",");
      sex          = strtok(NULL, ",");
      id            = strtok(NULL, ",");
      address   = strtok(NULL, ",");
}
Last edited on
Hi,
line is char[]?
strcount is string?

if that, "count" should be atoi(strcount.c_str())
It doesnt work!!!

Someone help!!!!
What do you want? complete working code? Oh common, it is spoon feeding and you won't learn anything. Paste what you got so far.
i follow for tips but it doesnt work, "NULL" is problem
Last edited on
Include iostream header file

Or if it will not work, include stddef.h

or if it will not work, use nullptr instead of NULL

Or if it will still not work, use 0 (zero) instead of NULL
Last edited on
If you can't do it, here is my code. This works for me. Check and understand it and don't just copy it without understanding. Better if you have questions in this code if you need clarification on the code so that you can understand better.

By the way, put the csv file inside C: drive since the file I opened as input is "C:\\input.csv". You can change this in the code if you have other location and name of the input csv 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cstring>

using namespace std;

typedef struct cus {
    string Name;
    string Sex;
    string ID;
    string Address;
} CUS;

int main()
{
    int         nCus = 0;
    vector<CUS> list;
    fstream     fi;
    string      line  = "";
    char       *token = nullptr;

    // Open input file
    fi.open("c:\\input.csv", ios::in);

    // Check if file is open, if not, exit from main
    if (!fi.is_open()) {
        return -1;
    }

    // Get the first line where the count of entries found
    getline(fi, line);
    // Print line read from file for debugging
    cout << "Line read from file: " << line << endl;

    // Get the string count value
    token = strtok((char *)line.c_str(), ",");
    // Check first if token is not null before using to avoid problems
    if (token != nullptr) {
        // Convert string count into an int count
        nCus = atoi(token);
    }

    //Print the count of customer for checking for debugging
    cout << "Number of entries in input file: " << nCus << endl;

    // Get each name entry and put into a structure then add the structure into a vector
    for (int i = 0; i < nCus; i++) {
        // Allocate memory for a name structure
        CUS *p = new CUS;

        // Read name entry from file
        getline(fi, line);
        // Print line read from file for debugging
        cout << "\nLine read from file: " << line << endl;

        // Break this line into tokens to get each info
        // This first token is the name, save it if its not null
        token = strtok((char *)line.c_str(), ",");
        if (token != nullptr) {
            string name(token); //Convert char * to string
            p->Name = name;
        }
        else {
            p->Name = "";       //Set an empty string if token for name is null
        }

        // Second token is sex ('0' for male ad '1' for female)
        // Put "Male" to struct if value read is '0', otherwise, 'Female'
        token = strtok(nullptr, ",");
        if (token != nullptr) {
            if (strcmp(token, "0") == 0) { //If token is '0', sex is "Male"
                p->Sex = "Male";
            }
            else {
                p->Sex = "Female"; // If not '0' then sex is "Female"
            }
        }
        else {
            p->Sex = "";       //Set an empty string if token for sex is null
        }

        // Third token is the ID, save it if its not null
        token = strtok(nullptr, ",");
        if (token != nullptr) {
            string ID(token); //Convert char * to string
            p->ID = ID;
        }
        else {
            p->ID = "";       //Set an empty string if token for ID is null
        }

        // Fourth token is the Address, save it if its not null
        token = strtok(nullptr, ",");
        if (token != nullptr) {
            string address(token); //Convert char * to string
            p->Address = address;
        }
        else {
            p->Address = "";       //Set an empty string if token for address is null
        }

        //Print all the name entry information found for tracing/debugging
        cout << "\nDisplaying name " << i + 1 << " information..." << endl;
        cout << "Name: " << p->Name << "\nSex: " << p->Sex << "\nID: " << p->ID << "\nAddress: " << p->Address << endl;

        //Now save this name entry info into a vector for further manipulation
        list.push_back(*p);
    }
    

    //Outside this loop, you can add whatever code you want if there is a need to manipulate or use the vector/list that contains all the input name entries. 
    return 0;
}
Last edited on
Thks, im checking
how if i need use fi.getline(name, 100, ',')...
I have a question

(char*)line.c_str()

line: string
linre.c_str() : char*

why you put (char*) before line.c_str()
Here is my code following ur tips. thks.
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
72
73
74
75
76
77
78
79
#include <iostream>
#include <vector>
#include <fstream>
#include <string>

using namespace std;

typedef struct Cus
{
	string name;
	int sex;
	string ID;
	string address;
	int balance;
}cus;

void main()
{
	fstream fi;
	fi.open("input.csv",ios::in);
	if (!fi)
	{
		cout << "Cant open " << endl;
		return;
	}

	vector <cus*> list;
	string line;
	char* token = NULL;

	// Number of customer
	getline(fi, line);
	token = strtok((char*)line.c_str(),",");
	int ncus = atoi(token);
	
	for (int i = 0; i < ncus; i++)
	{
		getline(fi, line);
		cus*p = new cus;
		// Name
		token = strtok((char*)line.c_str(), ",");
		string Name(token);
		p->name = Name;

		// Sex
		token = strtok(NULL, ",");
		p->sex = atoi(token);

		// ID
		token = strtok(NULL, ",");
		string id(token);
		p->ID = id;

		// Address
		token = strtok(NULL, ",");
		string Address(token);
		p->address = Address;

		//Balance
		token = strtok(NULL, ",");
		p->balance = atoi(token);

		list.push_back(p);
	}

	for (int i = 0; i < list.size(); i++)
	{
		cout << "- #" << i + 1 << endl;
		cout << "Name: " << list.at(i)->name << endl;
		cout << "Sex: ";
		if (list.at(i)->sex == 1) cout << "Male" << endl;
		else
			cout << "Female" << endl;
		cout << "ID: " << list.at(i)->ID << endl;
		cout << "Address: " << list.at(i)->address << endl;
		cout << "Balance: " << list.at(i)->balance << endl;
		cout << "--------------------------------------------" << endl;
	}
}


it have one more variable, but it not inportant.

By the way, is it ok if i use vector<cus*>?
Topic archived. No new replies allowed.