Files-CSVFiles-Cpp
Files-CSVFiles-Cpp
Define CSV
CSV Files
C++ can work with files besides just text files. Comma Separated Value (CSV)
files are an example of a commonly used file format for storing data. CSV
files are similar to a spreadsheet in that data is stored in rows and columns.
Each row of data is on its own line in the file, and commas are used to
indicate a new column. Here is an example of a CSV file.
You can read a CSV file in the same way you read a text file. First create an
ifstream object and then open the CSV file using it.
try {
ifstream file;
string read;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
while (getline(file, read, ',')) {
cout << read + ' ';
}
file.close();
}
catch (exception& e) {
cerr << e.what() << endl;
}
To iterate through the CSV file, we use while (getline(file, read, ',')).
Since CSV files contain commas that separate information, we set the
delimiter to ','. Then we print the content by using cout << read + ' '.
We add a space to separate the tokens from each other since it is not
apparent that the information is tokenized from using just cout << read;.
challenge
By using cout << read << endl; you can clearly see each token line by line.
Depending on your preference, you can choose to arrange the tokens in a
variety of different formats.
try {
ifstream file;
string read;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
file.ignore(19); //Ignore the first 19 characters from index
0-18
while (getline(file, read, ',')) {
cout << read << endl;
}
file.close();
}
catch (exception& e) {
cerr << e.what() << endl;
}
challenge
The file.ignore(500, '\n'); command tells the system to skip the first
500 characters or up through the newline character \n. Since there are
fewer than 500 characters, the system will skip everything up through the
first occurrence of the newline. You can add additional ignore commands
to ignore more lines of data if needed.
Printing CSV Data
try {
ifstream file;
string read;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
while (getline(file, read, ',')) {
cout << read + " ";
}
file.close();
}
catch (exception& e) {
cerr << e.what() << endl;
}
To better organize our CSV data, we can store the data into a vector and
then format and print elements in a way that looks more organized.
string path = "student/csv/homeruns.csv";
vector<string> data;
try {
ifstream file;
string read;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
while (getline(file, read)) {
stringstream ss(read);
while (getline(ss, read, ',')) {
data.push_back(read);
}
}
file.close();
for (int i = 0; i < data.size(); i++) {
if (i % 3 == 0) {
cout << setw(20) << left << data.at(i);
}
else if (i % 3 == 1) {
cout << setw(15) << left << data.at(i);
}
else {
cout << data.at(i) << endl;
}
}
}
catch (exception& e) {
cerr << e.what() << endl;
}
To organize our data, we use conditionals to split our elements into three
columns. if (i % 3 == 0) refers to the elements in the first column, else
if (i % 3 == 1) refers to the second column, and else refers to the third.
We use the setw() function to provide padding for our elements. For
example, setw(20) means that the system will reserve 20 characters for the
elements. If the element does not take up 20 characters, then white spaces
will occupy those spaces. To use setw(), you’ll need #include <iomanip> in
the header of your file. The left tag forces the element to be aligned to the
left side.
challenge
Notice how the last column Active Player is not formatted and is therefore
unaffected by the changes.
important
IMPORTANT
The order or placement of where you use left and setw() can affect all
streams that follow. So it’s important to keep track of the changes that
take place as you print. For example outputting
Writing to CSV Files
try {
ofstream file;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
file << "Greeting,Language" << endl;
file << "Hello,English" << endl;
file << "Bonjour,French" << endl;
file << "Hola,Spanish";
file.close();
ifstream file2;
string read;
file2.open(path);
while (getline(file2, read, ',')) {
cout << read + ' ';
}
file2.close();
}
To organize the CSV data, you can add each token into a vector and then
use conditionals to format and print the data like before.
string path = "student/csv/writepractice.csv";
vector<string> data;
try {
ifstream file;
string read;
file.open(path);
if (!file) {
throw runtime_error("File failed to open.");
}
while (getline(file, read)) {
stringstream ss(read);
while (getline(ss, read, ',')) {
data.push_back(read);
}
}
file.close();
for (int i = 0; i < data.size(); i++) {
if (i % 2 == 0) {
cout << setw(15) << left << data.at(i);
}
else {
cout << data.at(i) << endl;
}
}
}
catch (exception& e) {
cerr << e.what() << endl;
}