How to Read File Content into Istringstream

How to read file content into istringstream?

std::ifstream has a method rdbuf(), that returns a pointer to a filebuf. You can then "push" this filebuf into your stringstream:

#include <fstream>
#include <sstream>

int main()
{
std::ifstream file( "myFile" );

if ( file )
{
std::stringstream buffer;

buffer << file.rdbuf();

file.close();

// operations on the buffer...
}
}

EDIT: As Martin York remarks in the comments, this might not be the fastest solution since the stringstream's operator<< will read the filebuf character by character. You might want to check his answer, where he uses the ifstream's read method as you used to do, and then set the stringstream buffer to point to the previously allocated memory.

can't read from .txt file using istringstream

Assuming your goal was to read each of the entries in the file, you are using the wrong class. For reading from files, you need std::ifstream, and would use it as follows:

#include <iostream>
#include <fstream>
#include <string>

int main(int argc,char* argv[])
{
std::string filename = "test.txt";
std::ifstream file(filename);
if (file.is_open())
{
std::string line;
while (getline(file, line))
{
std::cout << "\n" << line;
}
}
else
{
// Handling for file not able to be opened
}
return 0;
}

OUTPUT:

<newline>
test1
test2
test3

Live Example

std::stringstream is used for parsing strings, not files.

How to use IStringStream to read from a file?

#include <fstream>

std::ifstream file("filename.txt");

StuffType stuff;
while(file >> stuff)
{
// If you are here you have successfully read stuff.
}

Read whole ASCII file into C++ std::string

Update: Turns out that this method, while following STL idioms well, is actually surprisingly inefficient! Don't do this with large files. (See: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html)

You can make a streambuf iterator out of the file and initialize the string with it:

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());

Not sure where you're getting the t.open("file.txt", "r") syntax from. As far as I know that's not a method that std::ifstream has. It looks like you've confused it with C's fopen.

Edit: Also note the extra parentheses around the first argument to the string constructor. These are essential. They prevent the problem known as the "most vexing parse", which in this case won't actually give you a compile error like it usually does, but will give you interesting (read: wrong) results.

Following KeithB's point in the comments, here's a way to do it that allocates all the memory up front (rather than relying on the string class's automatic reallocation):

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str;

t.seekg(0, std::ios::end);
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);

str.assign((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());

How to extract string with comma delimiter from txt file and parse every element separete by comma delimiter into a class constructor

Parsing CSV file is an old topic. You will find at least 100 answers with code examples here on stackoverflow. Very often you will find a solution with the function std::getline. Please read the documentation here. It can read characters from a std::ifstream until or up to a delimiter (a comma , in our case), then store the result, without the comma, in a string and discard the comma from the stream. So, throwing that away. The characters will be stored in a std::string. If numbers or other types are needed, we need to convert the string to the other type, using the appropriate function.

Example: We have a string consisting of characters ‘1’, ‘2’ and ‘3’, so, “123”. The quotes indicate the string type. If we want to convert this string into an integer, we can use for example the function std::stoi.

In your case, you have 2 double values. So, we would split the input of the file into strings and then convert the 2 strings with the double values in it, using the function std::stod.

What you need to know additionally is, that often a 2 step approach is used. This is done to prevent potential problems arising from extracting all the string parts from one csv line. So,

  • we first read a complete line,
  • then put that line into a std::istringstream, and finally
  • read input and split the CSV from there.

Then, the rest is simple. Just use std::getline to al the data that you need.

Last but not least, to read the file, we will simply open it, read line by line, create an “EmployeeAccount” and push that into a std::vector

At the end we do some debug output.

Please see below one of may potential implementation proposals:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>

class EmployeeAccount {
private:
//member variable
std::string acountNumber;
std::string title;
std::string firstname;
std::string lastname;
std::string company;
std::string salesperson;
double purchaseValue;
std::string prev_salestaff;
double commission;

public:

//overload constructor
EmployeeAccount(const std::string& employeeAccountInfo)
{
std::istringstream employeeAccountStream(employeeAccountInfo);
std::getline(employeeAccountStream, acountNumber, ',');
std::getline(employeeAccountStream, title, ',');
std::getline(employeeAccountStream, firstname, ',');
std::getline(employeeAccountStream, lastname, ',');
std::getline(employeeAccountStream, company, ',');
std::getline(employeeAccountStream, salesperson, ',');
std::string temp;
std::getline(employeeAccountStream, temp, ',');
purchaseValue = std::stod(temp);
std::getline(employeeAccountStream, prev_salestaff, ',');
std::getline(employeeAccountStream, temp, ',');
commission = std::stod(temp);
}
//Access methods
std::string getAccountNumber() const { return acountNumber; };
std::string getTitle() const { return title; };
std::string getFirstname() const { return firstname; };
std::string getLastname() const { return lastname; };
std::string getCompany() const { return company; };
double getPurchaseValue() const { return purchaseValue; };
std::string getPrev_salesstaff() const { return prev_salestaff; };
double getCommission() const { return commission; };
std::string getAccountDetail() const { return acountNumber + " " + title + " " + firstname + " " + lastname + " " + company;};

//Destructor
~EmployeeAccount() {};
};
int main() {
std::ifstream ifs{ "accounts.txt" };
if (ifs) {

// Here we will store all accounts
std::vector<EmployeeAccount> accounts{};

// Read the file line by line
std::string line{};
while (std::getline(ifs, line)) {

// Create one account by splitting the input line
EmployeeAccount account(line);

// Add the new accounts to the vector of accounts
accounts.push_back(account);
}

// Debug output. For all accounts that we read, output all data
for (const EmployeeAccount& account : accounts) {

std::cout << "\n--------------------------\n"
<< account.getAccountDetail() << '\n'
<< account.getAccountNumber() << '\n'
<< account.getTitle() << '\n'
<< account.getFirstname() << '\n'
<< account.getLastname() << '\n'
<< account.getCompany() << '\n'
<< account.getPurchaseValue() << '\n'
<< account.getPrev_salesstaff() << '\n'
<< account.getCommission() << '\n';
}
}
else
std::cerr << "\n*** Error: Could not open source file\n\n";
}



Related Topics



Leave a reply



Submit