Reading from file

I have ran into a problem while doing a project for a college course which I am unable to find a solution for.

I am tasked to make a program that reads from a file and outputs to the screen, all of which I have had no problem with however- the different things in the file are supposed to be separated by a comma, not spaces. Every time I put a comma in the program skips my while statement and outputs no information from the file.

I am looking for an explanation not just someone posting the correct code and thank you for taking your time!

Below is the information I am having output- which works fine. When commas take the place of the spaces the information no longer displays.

41082 20 15
30101 39.5 20
10201 40 10
50201 12 12
99201 62.75 25.5

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
#include <iostream>
#include <fstream> // FIle input and output [use constructor to create file]
#include <cstdlib> // Exit function prototype
#include <string>
#include <iomanip>
using namespace std;

void outputEmployee( int , double , double);

int main()
{

   ifstream inClientFile("employee.txt", ios::in);

   if (!inClientFile)
   {
      cerr << "Unable to open file" << endl;
      exit(EXIT_FAILURE);
   }

   int employeeID;
   double hoursWorked;
   double wage;
   

   cout << left << setw(20) << "Employee ID" << setw(20)
      << "Hours Worked" << setw(20) << "Hour Wage" << "Gross Pay" <<
      endl << fixed << showpoint;

   while ( inClientFile >> employeeID >> hoursWorked >> wage)
   {
      outputEmployee(employeeID, hoursWorked, wage);
   }
   return 0;
}

void outputEmployee(int empID, double hours, double hourPay)
{
   double gross = hours * hourPay;

   cout << setprecision(2) << left << setw(20) << empID 
      << setw(20) << hours << setw(20) << hourPay << gross << endl << fixed << showpoint;
}
Well, just like many of us have seen with 'cin', the extraction operator '>>' will stop at whitespace, and this includes reading from a file. That makes values separated by spaces really easy to parse.

If you want to read it with the commas in there, you'll have to extract and ignore the commas.
I do not understand how I extract it and ignore the commas. Like I stated it will not extract any data when I have commas in.
What does your file look like when you put the commas in?

Like this?

41082,20,15
30101,39.5,20
10201,40,10
50201,12,12
99201,62.75,25.5
Simple: after reading in a number, before reading the next number, read the next character.
If it is a comma, throw it away, otherwise put it back into the input buffer.

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
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>

template < typename T > std::istream& read_number( std::istream& stm, T& n )
{
    char c ;
    if( stm >> c && c != ',' ) /* not a comma, put it back */ stm.putback(c) ;
    return stm >> n ;
}

void read_values( std::istream& stm )
{
    int id ;
    double hours ;
    double wage ;

    while( read_number(stm,id) && read_number(stm,hours) && read_number(stm,wage) )
        std::cout << std::fixed << std::setprecision(2) << id << ' ' << hours << ' ' << wage << '\n' ;
    std::cout << "------------------------\n" ;
}

int main()
{
    std::istringstream stm_ssv( "41082 20 15\n30101 39.5 20\n10201 40 10\n50201 12 12\n99201 62.75 25.5" ) ;
    read_values( stm_ssv ) ;

    std::istringstream stm_csv( "41082,20, 15\n30101,39.5,20\n10201, 40,   10\n50201, 12, 12\n99201,62.75, 25.5" ) ;
    read_values( stm_csv ) ;

    std::istringstream stm_mixed( "41082 20,15\n30101 39.5, 20\n10201, 40 10\n50201,12,12\n99201 62.75 25.5" ) ;
    read_values( stm_mixed ) ;
}

http://coliru.stacked-crooked.com/a/a2a3942652d87ef6

Requires knowledge of locales and facets:

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 <locale>
#include <iostream>
#include <iomanip>
#include <vector>
#include <iomanip>
#include <sstream>

void read_values( std::istream& stm )
{
    // This ctype facet classifies comma as white space
    struct comma_is_ws : std::ctype<char> // http://en.cppreference.com/w/cpp/locale/ctype_char
    {
        static const mask* classification_table()
        {
            // start with the classic table ( C locale's table )
            static std::vector<mask> classification_table( classic_table(),  classic_table() + table_size ) ;
            
            static const unsigned char comma = ',' ;
            classification_table[comma] = space ; // comma is to be treated as whitespace
            return std::addressof( classification_table.front() ) ;
        }

        // do not delete the table, initial reference count == 0
        comma_is_ws() : std::ctype<char>( classification_table() ) {}
    };
    
    // replace the locale in the stream with one that treats comma as white space
    // ideally, wrap this in an raii shim which automagically restores the old locale
    auto old_locale( stm.imbue( std::locale( stm.getloc(), new comma_is_ws ) ) ) ;

    int id ;
    double hours ;
    double wage ;

    while( stm >> id && stm >> hours && stm >> wage )
        std::cout << std::fixed << std::setprecision(2) << id << ' ' << hours << ' ' << wage << '\n' ;
    std::cout << "------------------------\n" ;

    stm.imbue(old_locale) ; // restore the old locale
}

int main()
{
    std::istringstream stm_ssv( "41082 20 15\n30101 39.5 20\n10201 40 10\n50201 12 12\n99201 62.75 25.5" ) ;
    read_values( stm_ssv ) ;

    std::istringstream stm_csv( "41082,20, 15\n30101,39.5,20\n10201, 40,   10\n50201, 12, 12\n99201,62.75, 25.5" ) ;
    read_values( stm_csv ) ;

    std::istringstream stm_mixed( "41082 20,15\n30101 39.5, 20\n10201, 40 10\n50201,12,12\n99201 62.75 25.5" ) ;
    read_values( stm_mixed ) ;
}

http://coliru.stacked-crooked.com/a/ff60166d83267bf3
Last edited on
Thank you for that help, this does seem to me a little over my knowledge level though- I will be going through it and playing with these functions in order to solidify it in my brain. It seems like I get more help online then in college these days XD
Topic archived. No new replies allowed.