How to Read and Write a Stl C++ String

How to read and write a STL C++ string?

You are trying to mix C style I/O with C++ types. When using C++ you should use the std::cin and std::cout streams for console input and output.

#include <string>
#include <iostream>
...
std::string in;
std::string out("hello world");

std::cin >> in;
std::cout << out;

But when reading a string std::cin stops reading as soon as it encounters a space or new line. You may want to use std::getline to get a entire line of input from the console.

std::getline(std::cin, in);

You use the same methods with a file (when dealing with non binary data).

std::ofstream ofs("myfile.txt");

ofs << myString;

How to print a string in C++

#include <iostream>
std::cout << someString << "\n";

or

printf("%s\n",someString.c_str());

How to read a text file in a specific format c++

You could use std::remove_if

word.erase(std::remove_if(word.begin(), word.end(), [](char c)
{
return (c < 'a' || c > 'z') && c != '\'' && c != '-';
}), word.end());

What is the most elegant way to read a text file with c++?

There are many ways, you pick which is the most elegant for you.

Reading into char*:

ifstream file ("file.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
file.seekg(0, ios::end);
size = file.tellg();
char *contents = new char [size];
file.seekg (0, ios::beg);
file.read (contents, size);
file.close();
//... do something with it
delete [] contents;
}

Into std::string:

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

Into vector<char>:

std::ifstream in("file.txt");
std::vector<char> contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());

Into string, using stringstream:

std::ifstream in("file.txt");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());

file.txt is just an example, everything works fine for binary files as well, just make sure you use ios::binary in ifstream constructor.

STL reading from file

I am assuming you want to take in a buffer of characters.
So Words should be vector<char> In case your requirement is getting a container of const char* (that would be list of strings) you can build a solution of top of the vector of characters by splitting on your desired set of deliminator.

Words.resize(maxBufferSize);
fgets(Words.data(), maxBufferSize, fp);

See data for reference

I would have personally preferred using ifstream.

std::ifstream fin(filename);
std::vector<char> Words{ std::istream_iterator<char>{fin},
std::istream_iterator<char>{}};

In case your input file is already deliminated by whitespaces, then you can do

 std::vector<string> Words{ std::istream_iterator<string>{fin},
std::istream_iterator<string>{}};

As mentioned in the comments by using std::string you save yourself a lot of trouble around memory management etc.

GNU STL string: is copy-on-write involved here?

C++ doesn't distinguish between the operator[] for reading and writing, but only the operator[] for const object and mutable (non-const) object. Since a_copy is mutable, the mutable operator[] will be chosen, which forces the copying because that operator returns a (mutable) reference.

If efficiency is a concern, you could cast the a_copy to a const string to force the const version of operator[] to be used, which won't make a copy of the internal buffer.

char f = static_cast<const string>(a_copy)[99];

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 read files using containers in STL

You seem to need to inspect Dictionary to see if it contains each word you read, then choose which of KnownWords and UnknownWords to modify.

void WordStats::ReadTxtFile(){
std::ifstream ifile(Filename);
if(!ifile)
{
std::cerr << "Error Opening file " << Filename << std::endl;
exit(1);
}

I have cleaned up your local declarations, so variables are alive for as little time as necessary.

Assuming that the file contains words separated by spaces and newlines, read each word

    for (std::string word; ifile >> word; )
{

Make it lowercase

        transform (word.begin(), word.end(), word.begin(), ::tolower);

Then look to see if it is in Dictionary

        if (Dictionary.count(word))
{

Record the position in KnownWords[word].

            KnownWords[word].push_back(ifile.tellg());
}
else
{

Or in UnknownWords[word].

            UnknownWords[word].push_back(ifile.tellg()); 
}
}

Then display the sizes from those to get the desired output.

    std::cout << KnownWords.size() << " known words read." << std::endl;
std::cout << UnknownWords.size() << " unknown words read." << std::endl;
}

You could replace the conditional statement that duplicates the action, with a conditional expression. Note the reference type in the declaration of Words

WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
Words[word].push_back(ifile.tellg());

As a complete function:

void WordStats::ReadTxtFile(){
std::ifstream ifile(Filename);
if(!ifile)
{
std::cerr << "Error Opening file " << Filename << std::endl;
exit(1);
}

for (std::string word; ifile >> word; )
{
transform (word.begin(), word.end(), word.begin(), ::tolower);
WordMap & Words = (Dictionary.count(word) ? KnownWords : UnknownWords);
Words[word].push_back(ifile.tellg());
}

std::cout << KnownWords.size() << " known words read." << std::endl;
std::cout << UnknownWords.size() << " unknown words read." << std::endl;
}


Related Topics



Leave a reply



Submit