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 size
s 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
How to Correctly Initialize Member Variable of Template Type
Handling Partial Return from Recv() Tcp in C
Creating a Zip File on Windows (Xp/2003) in C/C++
How to Automatically Register a Class on Creation
Std::Unique_Ptr for C Functions That Need Free
Why Is a Char and a Bool the Same Size in C++
Cmake Find_Package Specify Path
Do I Have to Use #Include <String> Beside <Iostream>
Reading Line from Text File and Putting the Strings into a Vector
How to Read/Write a Struct in Binary Files
C++ How to Generate All the Permutations of Function Overloads
Correctly Reading a Utf-16 Text File into a String Without External Libraries
Cmake Does Not Find Visual C++ Compiler