Home > database >  i am trying to use getline to read a csv file line by line and separate the data in the file and tur
i am trying to use getline to read a csv file line by line and separate the data in the file and tur

Time:04-01

I am a beginner and I just need a bit of help on why I getline is showing an error:

this is what I have so far

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>

using namespace std;

const double TAX_RATE = 0.0825;
const int MAX_ITEMS = 1000;
const int MAX_TRANSACTIONS = 100;

int main(int argc, char const *argv[]){
    string fname = "";
    int itemCnt = 0, start = 0, end = 0;
    int ids[MAX_ITEMS], qtys[MAX_ITEMS];
    double costs[MAX_ITEMS], subtotals[MAX_TRANSACTIONS],
           taxes[MAX_TRANSACTIONS], totals[MAX_TRANSACTIONS];
    string names[MAX_ITEMS], paymentTypes[MAX_ITEMS], payments[MAX_ITEMS];
     ifstream iFile;

     if ( argc != 2 ) { 
        cout<<"usage: "<< argv[0]<< " <file name>" <<endl;
        return 0;
    } else  { 
        iFile.open(argv[1]);
    }
        if (!iFile) { 
           cout<<"Error: Invalid file name"<<endl;
           cin.clear();
        }             

        while (!iFile.eof())
    {
        getline(iFile,str); //this isn't working 

        int commaLoc = str.find(',');
        ids[itemCnt]= str.substr(0,commaLoc);
        str = str.substr(commaLoc  1, str.length());
        //string to int I'm not sure how to do I know its something with stoi() but not sure how to format it 

        }

        return 0;
}

I am able to get the file to open but I'm not sure why getline isn't working it keeps saying something like no instance of overload function

My csv file looks like: 1,Laptop,799.99,1,cash,1100

I need it to read the first number and because Its a string i don't know how to save it as an int

CodePudding user response:

Multiple errors. First there is nothing called 'str' in your program. I will guess its just a string used as a temp buffer

do not do this (!File.eof) it doesnt do what you think.

    while (iFile)
     {
         string str; <<<<<==== added
         getline(iFile,str); //this isn't working <<<===is now
         int commaLoc = str.find(',');

Next this line doesnt work because ids are ints and substring returns a string.

         //   ids[itemCnt]= str.substr(0,commaLoc);

          ids[itemCnt]= stoi(str.substr(0,commaLoc)); <<<<==== fixed
          str = str.substr(commaLoc  1, str.length());

    }

I strongly recommend you use std::vector instead of c-style fixed size arrays. Takes 5 minutes to learn how to use them and they have huge benefits. If you must use fixed size arrays use std::array instead of c-style

CodePudding user response:

You can read a string and try to convert it to a number in different ways. For example, since C 17, you can use from_chars. One of its overloads:

  • Receives a pair of begin and end char pointers, and an int variable,
  • tries to parse an int number, and
  • and returns the parsed number, together with a pointer to the first character that wasn't part of the match.
int i{};
auto [ptr, ec] = std::from_chars(str.data(), str.data()   str.size(), i);
if (ec == std::errc{}) { /* do something with i */} else { /* error */ }

[Demo]

Full code (using a istrinstream instead of a ifstream):

#include <charconv>  // from_chars
#include <iomanip>
#include <iostream>
#include <sstream>  // istringstream
#include <system_error>  // errc

constinit const int MAX_ITEMS = 10;

int main() {
    std::istringstream iss{
        "1,Laptop,799.99,1,cash,1100\n"
        "2,PC,688.88,2,card,1101\n"
        "blah,Keyboard,39.00,3,cash,1102"
    };

    size_t itemCnt{};
    int ids[MAX_ITEMS]{};
    std::string str{};
    while (std::getline(iss, str)) {
        // Parse counter
        int i{};
        auto [ptr, ec] = std::from_chars(str.data(), str.data()   str.size(), i);
        if (ec == std::errc{}) {
            ids[itemCnt] = i;

            // Remaining string
            std::string remaining_string{ str.substr(ptr - str.data()   1) };
            std::cout << ids[itemCnt] << ", " << remaining_string << "\n";
        }
        else {
            std::cout << "Error: invalid counter.\n";
        }

          itemCnt;
    }
}

// Outputs:
//
//   1, Laptop,799.99,1,cash,1100
//   2, PC,688.88,2,card,1101
//   Error: invalid counter.
  • Related