I am using the following loop to read an unknown number of lines from the console, but it is not working. After I have fed the input I keeping pressing enter but the loop does not stop.
vector<string> file;
string line;
while(getline(cin,line)
file.push_back(line);
Because getline will evaluate to true even if you push only enter.
You need to compare the read string to the empty string and break if true.
vector<string> file;
string line;
while(getline(cin,line))
{
if (line.empty())
break;
file.push_back(line);
}
Try:
vector<string> file;
string line;
while( getline(cin,line))
{
if( line.empty())
break;
file.push_back(line);
}
For getline is easy, as it is suggested by other answers:
string line;
while(getline(cin,line))
{
if (line.empty())
break;
file.push_back(line);
}
But to cin objects, I found a way to without the need for any breaking character. You have to use the same variable to cin all of the objects. After usage, you need to set it to a default exit value. Then check if your variable is the same after the next cin. Example:
string o;
while(true){
cin>>o;
if (o.compare("tmp")==0)
break;
// your normal code
o="tmp";
}
You should signal the end of file to your application. On Linux it is Ctrl-D, and it might be Ctrl-Z on some Microsoft systems
And your application should test of end of file condition using eof()
Related
How can I get and then store a space delimited input in C++ from a user into an array?
Most important part is that length is unknown and input should be by user during runtime
#include<iostream>
using namespace std;
int main() {
int n=0;
string names[3];
int i = 0;
while ( getline( cin, names[i]))
{
cout<<"i = "<<i<<"\n";
cout<<names[i]<<"\n";
i++;
cout<<"i = "<<i<<"\n";
}
for(i=0;i<3;i++)
{
cout<<names[i];
}
return 0;
}
The first problem I can spot in your code is, that you provide a fixed sized array of string names[3]; to store an unknown number of inputs from the user. That certainly won't work.
To fix this use a container that can use an "arbitrary" number of std::strings;
std::vector<std::string> names;
Having this you can just use something like
std::vector<std::string> names;
std::string name;
while(cin >> name) {
names.push_back(name);
}
The problem still left is how you could end this loop.
There are several options:
Let the user use one of CTRL-D or CTRL-Z (<- subtle link)
Ask them to enter a special value like quit, exit, -1 to end inputting
Track it down to a second level to process ENTER. Use std::getline() parse all the words using a std::istringstream or break, when getline() reads an empty result.
Let's analyze these:
Is a bad choice, because it's operating system dependent and asks the user to do relatively complicated actions.
Restricts the possible inputs, and there's a method needed to escape inputs of quit, exit or alike.
Empty input like retrieved from a simple additional hit of the ENTER key is probably the most intuitive you can offer to the user.
As a solution following my proposal in 3.:
std::string line;
std::vector<std::string> names;
while ( getline( cin, line)) {
if(line.empty()) {
// end input condition
break;
}
std::istringstream iss(line);
std::string name;
while(iss >> name) {
names.push_back(name);
}
}
I need help, I tried googling if I could find a similar problem but the solutions for others didn't work for me.
I'm trying to use getline() to read the file I've opened but it's not accepting the parameters I've given it.
What I'm trying to accomplish at this time (not the entire program) is to open a .csv file and determine how many elements it has inside by using getline() and using the , character as the delimiter. My loop has an index which I could just add 1 to it so that I can get the total number of elements inside the file.
The reason I'm doing this is because I intend to use it for a project at school but so far I've gotten stuck at the getline() error:
no matching function for call to 'std::basic_ifstream::getline(std::string&, int, const char [2])'
My code is here:
void readfile(string a)
{
int i = 0;
ifstream infile;
infile.open(a.c_str());
string temp;
//count how many elements are inside
if(infile.is_open())
{
while(infile.good())
{
infile.getline(temp, 256, ",");
i++;
}
infile.close();
i+=1;
}
else
{
cout<<"Error opening file.";
}
cout<<i;
}
Use the free getline() function:
std::string line;
getline(infile, line);
In addition to the answer by #UlrichEckhardt, I'd handle delimiters like this:
if(infile.is_open())
{
string temp;
// std::getline(std;:istream&, std::string) used below
while(getline(infile, temp)) {
std::stringstream stream(str);
std::string token;
while (std::getline(stream, token, ','))
if (!token.empty()) // it's up to you to decide how to handle empty tokens
i++;
}
}
Note the ','. If it were ".", this would be considered a string by the compiler, which is exactly what you're seeing in the error message: a '\0' is appended automatically, thus producing a char[2].
I have an input with the following from a text file using C++
command1 5 #Create 5 box
length 12
insertText THIS IS A BOX
how can i read in the input while ignoring anything after the #sign?
for example output should be without #Create 5 box
command1 5
length 12
insertText THIS IS A BOX
EDIT:
I tried the following:
while(getline(myfile, line))
{
istringstream readLine(line);
getline(readLine, command, ' ');
getline(readLine, input, '\0');
}
...but it doesn't seem to work.
The outer while(getline( and istringsteam are good, but after that you'd want to read a space-separated word into command, then perhaps one or more space-separated inputs after that: something like
std::string command, input;
std::vector<std::string> inputs;
if (readLine >> command && command[0] != '#')
{
while (readLine >> input && input[0] != '#')
inputs.push_back(input);
// process command and inputs...
}
It's easier to use >> than getline to parse readLine because they set the stream failure state if they don't get at least one valid character, making the [0] indexing safe and dropping out cleanly for empty lines, or commands with no inputs.
You can simply use std::getline() like this:
int main()
{
std::ifstream ifs("file.txt");
std::string line;
while(std::getline(ifs, line))
{
std::istringstream iss(line);
if(std::getline(iss, line, '#')) // only read up to '#'
{
// use line here
std::cout << line << '\n';
}
}
}
Output:
command1 5
length 12
insertText THIS IS A BOX
in your function where you check every character one by one, add this code: (pseudo code)
if(currChar == #){
while(currChar != '\n'){
getNextChar();// you arent saving it so youre ignoring it
}
}else{
Char c = getNextChar();
//now you can add this character to your output string
for example. You can use ignore(inputSize, "#") or you can use getline
http://www.cplusplus.com/reference/istream/istream/ignore/
http://www.cplusplus.com/reference/istream/istream/getline/
I'm using getline to get input and I want to store every line input to an array so that I can recall specific array content for further processing. Any ideas? Thanks in advance
string line;
while (true) {
getline(cin, line);
if (line.empty()) {
break;
}
// code
}
EDIT/ADD
Does anyone know why I cannot use cin before the while loop? When for example I put
cin >> var1; before the loop it won't go inside the loop at all!
ANSWERING MYSELF
I found this that solves it!
The simplest solution is to use vector container:
std::vector<std::string> arr;
and then:
arr.push_back(line);
Use vector<string> vec;
Better way to read from file would be as below
string line;
while (getline(cin, line)) {
if (line.empty()) {
break;
}
vec.push_back(line);
// code
}
once EOF is reached loop will break...
I used "cin" to read words from input stream, which like
int main( ){
string word;
while (cin >> word){
//do sth on the input word
}
// perform some other operations
}
The code structure is something like the above one. It is compilable. During the execution, I keep inputting something like
aa bb cc dd
My question is how to end this input? In other words, suppose the textfile is just "aa bb cc dd". But I do not know how to let the program know that the file ends.
Your code is correct. If you were interactively inputting, you would need to send a EOF character, such as CTRL-D.
This EOF character isn't needed when you are reading in a file. This is because once you hit the end of your input stream, there is nothing left to "cin"(because the stream is now closed), thus the while loop exits.
As others already answer this question, I would like add this important point:
Since Ctrl-Z on Windows (and Ctrl-D on unix systems) causes EOF to reach, and you exit from the while loop, but outside the while loop you cannot read further input, since the EOF is already reached.
So to enable reading using cin again, you need to clear eof flag, and all other failure flags, as shown below:
cin.clear();
After doing this, you can start reading input using cin once again!
int main() {
string word;
while (cin >> word) {
// do something on the input word.
if (foo)
break;
}
// perform some other operations.
}
Hit Ctrl-Z (Ctrl-D on *nix systems) and hit enter. That sends an EOF and invalidates the stream.
cin >> some_variable_or_manipulator will always evaluate to a reference to cin. If you want to check and see if there is more input still to read, you need to do something like this:
int main( ){
string word;
while (cin.good()){
cin >> word;
//do sth on the input word
}
// perform some other operations
}
This checks the stream's goodbit, which is set to true when none of eofbit, failbit, or badbit are set. If there is an error reading, or the stream received an EOF character (from reaching the end of a file or from the user at the keyboard pressing CTRL+D), cin.good() will return false, and break you out of the loop.
I guess you want to jump out at the end of file.
You can get the value of basic_ios::eof , it returns true at the end of stream.
Take the input from a file. Then you will find that the while loop terminates when your program stops taking input.
Actually cin stops taking input when it finds an EOF marker. Each input file ends with this EOF marker. When this EOF marker is encountered by operator>> it modifies the value of internal flag eofbit into false and consequently the while loop stops.
It helps me to terminate loop by hitting ENTER.
int main() {
string word;
while(getline(cin,word) && s.compare("\0") != 0) {
//do sth on the input word
}
// perform some other operations
}
You can make a check for a special word in input.
F.e. "stop":
int main( ){
string word;
while (cin >> word){
if(word == "stop")
break;
//do sth on the input word
}
// perform some other operations
}
you can try this
string word;
vector<string> words;
while (cin >> word) {
words.push_back(word);
if (cin.get() == '\n')
break;
}
in this way, you don't have to end with CTRL+D(Z). program will quit while sentence end
your program doesn't take in count white spaces. make difference between cin and getline...
here is an example with a trick: the program get input and prints output until you hit twice Enter to quit:
#include <iostream>
#include <string>
using namespace std;
int main(){
char c = '\0';
string word;
int nReturn = 0;
cout << "Hit Enter twice to quit\n\n";
while (cin.peek())
{
cin.get(c);
if(nReturn > 1)
break;
if('\n' == c)
nReturn++;
else
nReturn = 0;
word += c;
cout << word;
word = "";
}
cout << endl;
return 0;
}