C++ stream iterators - c++

I am trying to use the stream iterators to read and output words from the console. Here is my attempt:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
vector<string> stringVec;
copy(istream_iterator<string>(cin), istream_iterator<string>(), back_inserter(stringVec));
sort(stringVec.begin(), stringVec.end());
unique_copy(stringVec.cbegin(), stringVec.cend(), ostream_iterator<string> (cout, "\n"));
return 0;
}
When I input "this is it" and press Return in the console, the cursor there keeps on blinking (indicating that it's waiting for input).
Can anyone please offer some insights on my approach?
Thanks in advance.

You need to provide a EOF for istream_iterator<string>(), which constructs the end-of-stream iterator.
Use Ctrl+Z or F6 or (Ctrl+D on linux ) to stop getting input from stream

In your case, you can use getline and istringstream. It reads a string until \n and then passes it to copy.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
...
vector<string> stringVec;
string str;
getline(cin, str);
istringstream ss(str);
copy(istream_iterator<string>(ss),
istream_iterator<string>(),
back_inserter(stringVec));
sort(stringVec.begin(), stringVec.end());
unique_copy(stringVec.cbegin(),
stringVec.cend(),
ostream_iterator<string> (cout, "\n"));
Two same questions in a day, you can read this.

Related

How to use the delim parameter from getline

I need to make a program in witch I have to read a text from an input file(ifstream fin("input.in")) and store it until the program meets the "#" character. I know it should be doable using fin.getline, but I can't make the "delim" parameter work. I would find useful an explanation of how doe it work, and an example. I already read this, but I couldn't find an example with fin.getline.
This is what I tried, but it doesn't work:
#include <fstream>
#include <string.h>
#include <string>
using namespace std;
ifstream fin("cod.in");
ofstream fout("cod.out");
char chr[100];
for(int i=0;i<n;i++)
{
fin.getline(chr,'#');
fout<<chr<<" ";
}

Getline function is undefined, even though <string> header is included

I have looked at a few other questions regarding getline() not functioning, however most problems regarding the topic were due to the programmer not including the string header. I have the string header included however getline is still giving me error E0304 (which I have already looked into).
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
char input[100];
getline(cin, input);
cout << input << endl;
}
There are two forms of getline:
std::cin.getline(array, size); // reads into raw character array
getline(std::cin, string); // reads into std::string
You should use a std::string instead of a raw character array:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string input;
getline(std::cin, input);
std::cout << input << "\n";
}
The non-member getline only works with std::string. Use the std::istream member function getline for C-style strings:
std::cin.getline(input, sizeof(input));

Unable to tokenize a string and pass to a vector <string>

I am experimenting with CGI in C++. I know that there are libraries which handle basic stuff, but in order to know whats going on under the hood i have been trying to parse the stdin using string datatype ---> tokenize using '= and &' then push_back into a vector. at the latter step, i am receiving segmentation fault. given below is the program where i am using cin>> to obtain user input and so on ..
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int main()
{
vector <string> stuff(0);
vector<string>::iterator it;
char* bufferchar;
string buffer;
char str[size];
cout<<"Content-type: text/html\n\n"
<<"<html>"
<<"<head>"
<<"<title>CGI SCRIPT</title>"
<<"</head>"
<<"<body>"
fgets(str,20,stdin); //20 is expect size of content from html form
puts(str);
cout<<"<p>Now to break this guy apart";
int x=0;
bufferchar = strtok(str,"&=");
buffer+=bufferchar;
stuff.push_back(buffer);
while(bufferchar!=NULL){
cout<<bufferchar<<'\n'<<'\n';
bufferchar=strtok(NULL,"&=");
buffer+=bufferchar;
stuff.push_back(buffer);
}
cout<<"<br>ok does the vector iterate ?";
for (it=stuff.begin();it!=stuff.end();++it){
cout<<*it;
cout<<"<br> ok man, next <br><br>";
}
cout<<"</body>";
cout<<"</html>";
}

How to write vector values to a file

I have a large vector.
The ways that I use multiply the run-time of the program hugely. The first is write all values to a string as they are calculated using stringstreams and later write the string to a file. The other method is to make a long string after the fact and write that to the file. However, both of these are very slow.
Is there a way to just write the vector's values to the text file immediately with line breaks?
Using std::ofstream, std::ostream_iterator and std::copy() is the usual way to do this. Here is an example with std::strings using C++98 syntax (the question was asked pre-C++11):
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> example;
example.push_back("this");
example.push_back("is");
example.push_back("a");
example.push_back("test");
std::ofstream output_file("./example.txt");
std::ostream_iterator<std::string> output_iterator(output_file, "\n");
std::copy(example.begin(), example.end(), output_iterator);
}
[Some years later]
A more modern implementation may look like:
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> example { "This", "is", "a", "test" };
std::ofstream output_file("./example.txt");
std::ostream_iterator<std::string> output_iterator(output_file, "\n");
std::copy(std::begin(example), std::end(example), output_iterator);
}
Assuming you have C++11:
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> v{ "one", "two", "three" };
std::ofstream outFile("my_file.txt");
// the important part
for (const auto &e : v) outFile << e << "\n";
}
Maybe I have missed something, but what is wrong with:
std::ofstream f("somefile.txt");
for(vector<X>::const_iterator i = v.begin(); i != v.end(); ++i) {
f << *i << '\n';
}
That avoids having to do potentially quadratic string concatenation, which I assume is what's killing your run-time.
You can use std::copy and std::ostream_iterator.

std has no member 'getline'?

I'm trying to use std::getline, but my compiler is telling me that getline isn't identified?
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <fstream>
#include <cstdlib>
int main(){
using namespace std;
string line;
ifstream ifile("test.in");
if(ifile.is_open()){
while(ifile.good()){
getline(ifile,line);
}
}
}
std::getline is defined in the string header.
#include <string>
Also, your code isn't using anything from cstring, cstdio, cmath, or cstdlib; why bother including these?
EDIT: To clarify the confusion regarding the cstring and string headers, cstring pulls the contents of the C runtime library's string.h into the std namespace; string is part of the C++ standard library and contains getline, std::basic_string<> (and its specializations std::string and std::wstring), etc. -- two very different headers.
As ildjarn points out, the function is declared in <string>, and I'm suprised you didn't get an error at:
string line;
Also, this:
while(ifile.good()){
getline(ifile,line);
}
is not the way to write a read loop. You MUST test the success of the read operation, not the current stream state. You want:
while( getline(ifile,line) ) {
}
this is happening because getline comes from the string library, you need to #include <string> or #include <cstring>