C++ file io – Part 2

Spread the love

The CSV format – c++ file io

In the last article, we were looking at this csv file format that was contrived into the coding below.

There are definitely better ways of doing these things, but that was a quick dirty test.

Lets do it better, but first lets once more show the contrived version.

#include <fstream>

using namespace std;

int main(){
 string st1 = "'George','Stevens',89,56,90,85\n";
 string st2 = "'Samuels','Sawchuck',89,56,90,85\n";
 string st3 = "'Robert','Smith',89,56,90,85\n";
 string st4 = "'Janice','Merkel - Stevens',89,56,90,85\n";
 string st5 = "'D\'arcy','Mason',89,56,90,85\n";

   ofstream f;
   f.open("myOutPut.txt",ios::out | ios::app);
   f << "\n" << st1 << st2 << st3 << st3 << st4 << st5;
   f.close();
}

Output of myOutPut.txt file shown below

Graphical white on blue text output from the c++ file io stream above.

Yep, thanks. We know its ugly looking, but it works and gives us a base to clean up and ask the user for their input.

In the last lesson, we determined that it would be better to ask the user for the fname, lname and 4 class grades. Then we do this in a loop 5 times.

Then we can throw it into the file.

But if we use the exact order above, we are going to have to store the variables somewhere and run the risk of being interrupted during the process and not getting any data put into the file.

So, to streamline the process and avoid using vectors or arrays, we will instead ask the user for each line of data and immediately push that into the designated file. This will make the code shorter and cleaner.

#include <iostream>
#include <fstream>
#include <string>  // for the to_string function

using namespace std;

int main(){

   string fname,lname, s_concat;
   ofstream f;
   f.open("myOutPut.txt",ios::out | ios::app);
   int i;
   int exam1,exam2,exam3,exam4,exam5;
   for ( i = 0; i < 2; i++){
       cout << "Input Firstname, Lastname and 4 class exam results\n";
       cin >> fname >> lname >> exam1 >> exam2  
           >> exam3 >> exam4 >> exam5;
   // immediately write to the file
      s_concat = "'"+fname+"','"+lname+"',"+to_string(exam1)+","+to_string(exam2)+","+to_string(exam3)+","+to_string(exam4)+","+to_string(exam5)+"\n";
      cout << s_concat;
      f << s_concat;
   }   
   f.close();
}

What does the Code above do?

It declares 3 string variables including firstname, lastname and s_concat, then a file object and an int.

It then loops a number of times ( currently set for 2 ) in order to allow the user to input the fname, lname and 5 subject scores. For simplicity’s sake, it didn’t check to see if the scores were alpha or numeric only.

It then concatenated the string and put it into a varible to be pushed out onto the screen for debugging, before putting it into the file via a very simple

f << s_concat;

After doing the loop, it closed the file.

Thus the end of the write to CSV function. But its not and the output below is not as good as it could be.

The problem with the above block of data is that we used this construct to create our strings and the problem is that the single quote often shows up in a name like D’arcy.

The reason that we have this problem is because our concatenation of the string took this form below …

      s_concat = "'"+fname+"','"+lname+"',"+to_string(exam1)+","+to_string(exam2)+","+to_string(exam3)+","+to_string(exam4)+","+to_string(exam5)+"\n";

In the data above, we end up with ‘D’arcy’ which would probably confuse a csv converter that was trying to import the file into Excel or other spreadsheets.

Furthermore, although not all csv files have headers, we do know the column names, so why don’t we write a header as the first line before we start looping.

So, we fixed the single quote double quote problem with the code below

#include <iostream>
.
.
.
      s_concat = "\""+fname+"\",\""+lname+"\","+to_string(exam1)+","+to_string(exam2)+","+to_string(exam3)+","+to_string(exam4)+","+to_string(exam5)+"\n";
      cout << s_concat;
      f << s_concat;

Note the tricky part: s_concat = “\””+fname+”\”,\””+lname+”\”,”+ which was required in order to get something like “Charles”,”Madison” or a name like “D’angelo” or “D’arcy”


Ok, so other than poor code construction, there is one other little problem.

If a person’s first or last name includes spaces, cin << fname utterly ignores the second, third or fourth names. Yesss. it does.

To fix that, we have to use something like cin.getline(fname,sizeOfArray). This would enable us to properly accommodate concatenated last names like “Mendoza Richardson” or “Samuels Marshall”

So, lets do that and put the entire code in the next block.

#include <iostream>
#include <fstream>
#include <string>  // for the to_string function

using namespace std;

string convertToString(char* a) 
{ 
    string s = a; 
    return s; 
} 

int main(){
   char fname[60],lname[60];
   string s_concat,s_fname,s_lname;
   ofstream f;
   f.open("myOutPut.txt",ios::out | ios::app);
   int i;
   int exam1,exam2,exam3,exam4,exam5;
   f << "Firstname " << "Lastname " << "exam1 " << " exam2" << " Exam3" << " Exam4" << " Exam5\n";
   for ( i = 0; i < 2; i++){
       cout << "Input Firstname, Lastname and 4 class exam results\n";
       cin.getline(fname,60);  
       cin.getline(lname,60); 
       cin >> exam1 >> exam2 >> exam3 >> exam4 >> exam5;
   // immediately write to the file

       s_fname = convertToString(fname);
       s_lname = convertToString(lname);
      s_concat = "\""+s_fname+"\",\""+s_lname+"\","+to_string(exam1)+","+to_string(exam2)+","+to_string(exam3)+","+to_string(exam4)+","+to_string(exam5)+"\n";
      cout << s_concat;
      f << s_concat;
      cin.clear();
      cin.ignore();
   }   
   f.close();
}

Quite a few little things to explain but first, let’s show you the output.

It handles firstname and lastname’s with or without spaces or periods.

It uses the double quotation on the first two strings and leaves the rest of the numbers without strings. If you import this into Excel or Google Sheets, the numbers will be recognized properly as numbers and not text.

It creates the header easily enough so that Microsoft Access, Excel, Google Sheets and other spreadsheets can optionally use this.

c++ file io – write to json

Top