How to read raw input in cpp - c++

Imagine I want to copy-paste some text in stdin and I want to read it entirely in cpp (including whitespace). How can I do it? If I use cin, it reads tokens delimited by whitespace. If I do:
string text
string s;
while(cin>>s){
text += s;
}
Then it gets indistinguishable whether it was space(" ") or newline("\n") between tokens.
Question is, how can I read the whole string.

If you want something that is quick to code, use std::istream::getc.
std::string text;
char c;
while ( std::cin.getc(c) )
{
text.push_back(c);
}
If you expect the content of stdin to be large, this will be a performance problem. You should consider using std::istream::read for such use cases.

To make the result of the provided while loop approach distinguishable, I had to read it with readline() like this:
string text
string s;
while(readline(cin,s)){
text += s + "\n";
}
This way, it's guaranteed that readline will read the whole line (with spaces) and the given tokens will be only delimited by "\n" (which can be added manually).

From cplusplusreference.com:
As an object of class istream, characters can be retrieved either as
formatted data using the extraction operator (operator>>) or as
unformatted data, using member functions such as read.
cin - C++ Reference
I get:
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
char c;
string text;
while (!cin.read(&c, 1).eof())
s += c;
cout << "string was " << s << endl;
}
On Windows, end it with a <Ctrl-Z> on a line by itself, followed by <Enter>. I tested it, and it does indeed include the end of line characters.

Related

fastest way to read and parse text from stdin at the same time

Using C++ on Linux I am parsing(for words based on multiply delimiters) a big input that is provided via the stdin(no other way).
I read the stdinput using std::getline and then parse the line using the following pseudo code.
for (std::string single_line; std::getline(std::cin, single_line);)
{
std::string single_word;
for (auto single_charecter : single_line)
{
//do parsing based on a delimiter and
// create a word
}
}
My question is regarding the efficiency of me using std::getline and then parsing the line one char at a time.
Cant this be improved using other function calls or maybe some approach that includes the use of threads?
From what I understand, you are trying to parse a text input and trying to create words based on delimiters. If this is the case, you don't need to parse one line at a time. You can directly use stringstream Class and getline Method to Parse String Using a Delimiter Try this -
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using std::cout; using std::cin;
using std::endl; using std::string;
using std::vector; using std::stringstream;
int main(){
string text = "He said. The challenge Hector heard with joy, "
"Then with his spear restrain'd the youth of Troy ";
char del = ' ';
vector<string> words{};
stringstream sstream(text);
string word;
while (std::getline(sstream, word, del))
words.push_back(word);
for (const auto &str : words) {
cout << str << endl;
}
return EXIT_SUCCESS;
}
OUTPUT -
He
said.
The
...
Troy
In this method, we are putting text string variable into a stringstream to operate on it with the getline method. getline extracts characters until the given char is found and stores the token in the string variable. Notice that this method can only be applied when a single character delimiter is needed.

How to take multiple line string input in C++?

I am learning C++. I want to take multiple line string as input but I can't. I am using getline() for it but it is taking only one line input. When I press enter for writing next line it stoped taking input and print the first line.
I want to give input like the example below
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
But it takes only the first line input.
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
Please help me to know how can I do that.
Thank you.
Either you write a loop to read individual lines and concatenate them to a single string, thats what this answer suggests. If you are fine with designating a specific character to signal the end of the input, you can use the getline overload that takes a delimiter as parameter:
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin,s,'x');
std::cout << s;
}
The user would have to type an x to end input, so this input
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
x
would result in this output:
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
Of course this won't work when the string to be entered contains x, which renders the approach rather useless.
However, instead of using a "real" character as delimiter you can use the EOF character (EOF = end of file) like this:
std::getline(std::cin, s, static_cast<char>(EOF));
Then input is terminated by whatever your terminal interprets as EOF, eg Ctrl-d in linux.
Thanks to #darcamo for enlightening me on the EOF part.
You can only read one line at a time with std::getline if you don’t provide your own delimiter. If you want to accumulate multiple lines, one at a time, you need a place to put the result. Define a second string. Read a line at a time into s with std::getline, and then append s to the result string. Like this:
std::string result;
std::string s;
while (std::getline(std::cin, s))
result += s;
You can take several lines using the code below if you know how many lines you will input.
int line=3, t;
string s, bigString;
for(int i=0 ; i<line ; i++)
{
getline(cin,s); // This is to input the sentence
bigString += s + "\n";
}
cout << bigString;
If you don't know how many lines you will input (Input from file until end of file) then you can check this.
string s;
vector<string> all;
while(getline(cin,s))
{
all.push_back(s);// This is to input the sentence
}
for(auto i:all)
{
cout << i << endl;
}

Streaming I/O in c++

I am trying to get this file stream program to work but when I run it all that happens is it outputs "Writing" instead of outputting the file. What am i doing wrong?
#include "stdafx.h"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char str[10];
ifstream b_file ( "ioTest.txt" );
b_file>> str;
cout<< str <<"\n";
cin.get();
}
The standard input streams use whitespace as a delimiter for input. If you try extracting to a string, it will extract every character until a whitespace character is found. If you need the entire content of the file, here are a few options:
while (in >> word)
while (b_file >> word)
{
std::cout << word;
}
This method will iterate over each whitespace-separated tokens in the input stream.
std::getline()
while (std::getline(b_file, line))
{
std::cout << line;
}
std::getline() retrieves line-wise input, meaning it will extract every character until it reaches a delimiter. The delimiter by default is the newline but it can be specified as a third argument.
std::istream_iterator<T>
std::copy(std::istream_iterator<std::string>(b_file),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
std::istream_iterator is a special-purpose stream iterator class designed to "iterate" over tokens of type T from an input stream.
rdbuf()
std::cout << b_file.rdbuf();
This is more low-level. An overload of std::ostream::operator<<() takes a stream buffer pointer as an argument, and it will extract characters directly from the buffer.

Getting input from file troubles C++

I've been trying to read some information in from a .txt file in C++ but it's not all working like I expect. Here is some example code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[255];
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
And test.txt contains:
1234
WordOne WordTwo
What I expect is for the code to print the two lines contained in the text file, but instead I just get:
1234
I've been reading about getline and istream but can't seem to find any solutions so any help would be appreciated.
Thanks
The newline character remains in the input stream after the read of the integer:
// Always check result to ensure variables correctly assigned a value.
if (input_stream >> value)
{
}
Then, the call to getline() reads the newline character and stops, producing an empty string. To correct, consume the newline character before calling getline() (options include using getline() or ignore()).
Note there is a version std::getline() that accepts a std::string as its argument to avoid using a fixed sized array of char, which is used incorrectly in the posted code.
ifstream's getline method gathers input until one of two options is hit. Either a terminating character or the size passed in is reached. In your case, the newline terminator is encountered before the size is reached.
Use another getline to retrieve the second line of text.
Reference
The problem you are seeing is that the first newline after 1234 is not consumed by input_stream>>(int); so the next getline only reads to the end of that file.
This is a very constructed scenario, commonly found in schoolwork. The more common scenario when reading a textfile is to consider the entire file as linebased text.
In this case the more convenient
string line;
while( std::getline( input_stream, line ) ){
}
is appropriate, and way less error prone.
The textfile would commonly have a predefined format. Perhaps name = value lines, and are parsed as such after the line is read from the file.
Here is a somewhat corrected version of your original code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[256]; // was 255
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.ignore(); // skip '\n'
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
Also, I would advise you to use a string instead of a char[] and use the other getline function.

How to read the string into a file C++

i have a little problem on writing the string into a file,
How can i write the string into the file and able to view it as ascii text?
because i am able to do that when i set the default value for str but not when i enter a str data
Thanks.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream out("G://Test.txt");
if(!out) {
cout << "Cannot open output file.\n";
return 1;
}
char str[200];
cout << "Enter Customers data seperate by tab\n";
cin >> str;
cin.ignore();
out.write(str, strlen(str));
out.seekp(0 ,ios::end);
out.close();
return 0;
}
Please use std::string:
#include <string>
std::string str;
std::getline(cin, str);
cout << str;
I'm not sure what the exact problem in your case was, but >> only reads up to the first separator (which is whitespace); getline will read the entire line.
Just note that >> operator will read 1 word.
std::string word;
std::cin >> word; // reads one space seporated word.
// Ignores any initial space. Then read
// into 'word' all character upto (but not including)
// the first space character (the space is gone.
// Note. Space => White Space (' ', '\t', '\v' etc...)
You're working at the wrong level of abstraction. Also, there is no need to seekp to the end of the file before closing the file.
You want to read a string and write a string. As Pavel Minaev has said, this is directly supported via std::string and std::fstream:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ofstream out("G:\\Test.txt");
if(!out) {
std::cout << "Cannot open output file.\n";
return 1;
}
std::cout << "Enter Customer's data seperated by tab\n";
std::string buffer;
std::getline(std::cin, buffer);
out << buffer;
return 0;
}
If you want to write C, use C. Otherwise, take advantage of the language you're using.
I can't believe no one found the problem. The problem was that you were using strlen on a string that wasn't terminated with a null character. strlen will keep iterating until it finds a zero-byte, and an incorrect string length might be returned (or the program might crash - it's Undefined Behavior, who knows?).
The answer is to zero-initialize your string:
char str[200] = {0};
Supplying your own string as the value of str works because those in-memory strings are null-terminated.