using input redirection in while loop - c++

I need to create a program that reads in a list of random integers via input redirection and performs various tasks with them. For the purpose of this question I just want to print the sum of each number + 1. Trouble is, I don’t know how to get it to perform the operation on anything but the first number in the list. My mini program (program.cpp) is
#include <iostream>
using namespace std;
int main () {
int input;
bool arb = true;
cin >> input;
while (arb) {
cout << input + 1 << endl;
}
return 0;
}
and a sample textfile (textfile.txt) I'm using contains
9
8
7
6
When I run it it prints out “10” for infinity. What I’d like it do is print out
10
9
8
7
or the equivalent for whatever other text file may be used.
I thought maybe I could somehow reference specific lines in the textfile, but from searching how to do that all the similar questions I could find seemed to have solutions that required fstream, which is something I haven’t learned yet and therefore I’m not allowed to use it (this is for a class assignment).
The only compiler directives I’ve learned are iostream, string, cmath, iomanip, cstdlib, and ctime. The ways to get input I’ve learned are cin >> input, cin.get(input), and cin.getline(input), so if there are other ways of reading in the file besides those 3 that I’m unaware of, unfortunately I can’t use it. Note that my program HAS to use a while loop. The way the program will be run is
./program < whatevertextfile.txt
which I can't change.
given these restrictions, how can I get my program to read in and use each integer in the text file?

The idiomatic way to read a sequence of white-space separated integers in C++ would be
#include <iostream>
using namespace std;
int main () {
int input;
while (cin >> input) {
cout << input + 1 << endl;
}
return 0;
}
Let's come to why this works the way it does.
cin >> input
discards possible white-space and then reads an integer from the standard input. Moreover, it returns a reference of the cin object used. With this returned reference, you can call the bool conversion operator to check if any of the fail bits is set in the given std::basic_ios object. So
while (cin >> input)
does two things. Read an integer from standard input and check if it successfully completed the operation. As long as this operation succeeds, your while loop continues to iterate and you print the numbers.
See http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt for reference on std::basic_istream::operator>>.
See http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool for reference on operator bool.
Edit1: Move references to bottom so that the answer is more readable.

Related

integers, chars and floating points in structs

So, I'm having some issues with my c++ code. I have the following code, but so far I can't get most of the data stored into the structured data type.
//structured data declaration
struct item
{
int itemCode;
char description[20];
float price;
};
And then the get code looks like this.
cout << setprecision(2) << fixed << showpoint;
ofstream salesFile ("Sales.txt");
ifstream stockFile ("Stock.txt");
for (counter = 0; counter < 9; counter++)
{
stockFile >> instock[counter].itemCode;
stockFile.getline (instock[counter].description, 20);
stockFile >> instock[counter].price;
}
The output should have looked like:
1234 "description here" 999.99
Quantity X
And this was the output:
1234 0.00
Quantity 5
If you have a file format that is of the form (for one entry)
1234
description here
999.99
(across multiple lines) then the explanation is simple
Th reading code in your loop, which does
stockFile >> instock[counter].itemCode;
stockFile.getline (instock[counter].description, 20);
stockFile >> instock[counter].price;
will work in this sequence
The value of instock[counter].itemCode will receive the value 1234. However (and this is important to understand) the newline after the 1234 will still be waiting in the stream to be read.
The call of getline() will encounter the newline, and return immediately. instock[counter].description will contain the string "".
The expression stockFile >> instock[counter].price will encounter the d in description. This cannot be interpreted as an integral value, so instock[counter].price will be unchanged.
Assuming some preceding code (which you haven't shown) sets instock[counter].price to 999.99 the above sequence of events will explain your output.
The real problem is that you are mixing styles of input on the one stream. In this case, mixing usage of streaming operators >> with use of line-oriented input (getline()). As per my description of the sequence above, different styles of input interact in different ways, because (as in this case) they behave differently when encountering a newline.
Some people will just tell you to skip over the newline after reading instock[counter].itemCode. That advice is flawed, since it doesn't cope well with changes (e.g. what happens if the file format changes to include an additional field on another line?, what happens if the file isn't "quite" in the expected format for some reason?).
The more general solution is to avoid mixing styles of input on the one stream. A common way would be to use getline() to read all data from the stream (i.e. not use >> to interact directly with stockFile). Then interpret/parse each string to find the information needed.
Incidentally, rather than using arrays of char to hold a string, try using the standard std::string (from standard header <string>). This has the advantage that std::string can adjust its length as needed. std::getline() also has an overload that can happily read to an std::string. Once data is read from your stream as an std::string, it can be interpreted as needed.
There are many ways of interpreting a string (e.g. to extract integral values from it). I'll leave finding an approach for that as an exercise - you will learn more by doing it yourself.

Why does cin, expecting an int, change the corresponding int variable to zero in case of invalid input? [duplicate]

This question already has answers here:
Why does stringstream >> change value of target on failure?
(2 answers)
Closed 7 years ago.
I am completely new to C++ and am trying to write an extremely basic program, but I am having issues with initializing an integer. I have stripped it down to a very small program that still has the issue:
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter your age\n";
int age = -1;
cin >> age;
cout <<"\n\n Your age is " << age << "\n\n";
}
I read that if I attempt to input a string, e.g. abc to the age variable, then the input should fail and the value should be left alone and therefore it should print Your age is -1.
However, when I run this program and type abc, then it prints Your age is 0. Why?
The behavior you want to observe changed in 2011. Until then:
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
But since C++11:
If extraction fails, zero is written to value and failbit is set. [...]
(From cppr.)
With the compiler I tested against (gcc 4.8.4), the value is set to zero (for the 'abc' input) regardless of which version of the standard I compile against. Note also that it is set to minimum/maximum values if you provide a valid integer that is outside of the supported range of the variable that you are assigning to.
A more important point though, is that ignoring error flags is a recipe for disaster. Once you have an error in the input, any subsequent input is suspect (without hacks like ignore()). Situations like this are a good candidate for using exception handling.
Here's how I might implement what you are trying to do (but, again, considering the case of multiple inputs, recovering from errors is a messy business):
cin.exceptions( ~std::ios::goodbit );
try { cin >> age; }
catch ( std::ios::failure const & )
{
age=-1;
cin.clear();
cin.ignore(999,'\n');
}
or without exeptions:
cin >> age;
if ( cin.fail() ) age=-1, cin.clear(), cin.ignore(999,'\n');
See here for similar questions:
Why does stringstream >> change value of target on failure?
istream behavior change in C++ upon failure
Here are up-to-date docs for the operator in question:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt

How do the different ways to read strings from console actually differ? Operator <<, getline or cin.getline?

Let's suppose I'd like to read an integer from the console, and I would not like the program to break if it is fed non-integer characters. This is how I would do this:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string input; int n;
cin >> input;
if(!(stringstream(input)>>n)) cout << "Bad input!\n";
else cout << n;
return 0;
}
However, I see that http://www.cplusplus.com/doc/tutorial/basic_io/ uses getline(cin,input) rather than cin >> input. Are there any relevant differences between the two methods?
Also I wonder, since string is supposed not to have any length limits... What would happen if someone passed a 10GB long string to this program? Wouldn't it be safer to store the input in a limited-length char table and use, for example, cin.getline(input,256)?
std::getline gets a line (including spaces) and also reads (but discards) the ending newline. The input operator >> reads a whitespace-delimited "word".
For example, if your input is
123 456 789
Using std::getline will give you the string "123 456 789", but using the input operator >> you will get only "123".
And theoretically there's no limit to std::string, but in reality it's of course limited to the amount of memory it can allocate.
the first gets a line,
the second gets a world.if your input "hello world"
getline(cin,str) : str=="hello world"
cin>>str: str="hello"
and dont worry about out of range, like vector ,string can grow
operator>> reads a word (i.e. up to next whitespace-character)
std::getline() reads a "line" (by default up to next newline, but you can configure the delimiter) and stores the result in a std::string
istream::getline() reads a "line" in a fashion similar to std::getline(), but takes a char-array as its target. (This is the one you'll find as cin.getline())
If you get a 10 GB line passed to your program, then you'll either run out of memory on a 32-bit system, or take a while to parse it, potentially swapping a fair bit of memory to disk on a 64-bit system.
Whether arbitrary line-length size limitations make sense, really boils down to what kind of data your program expects to handle, as well as what kind of error you want to produce when you get too much data. (Presumably it is not acceptable behaviour to simply ignore the rest of the data, so you'll want to either read and perform work on it in parts, or error out)

C++ Programming Syntax and function assistance? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Okay so still new to the syntax of the C++ programming language and have come across a few things that are shown in examples but don't quite explain things on a level for someone to fully understand what it is.
For example if you were going to create a variable say : int x = 0; what does the zero part do, sets it to zero or holds a false value? Particullary in the code below.
Also some explanation on : if (!(cin>> input)) input = 0 if (!(cin>> 0)? if its not zero? seems like zero holds some other value.
Also cin.clear() and cin.ignore sure i've heard it clears the next line or erases something but really a thorough explanation of whats going on with this would really help?
Can't really move on to bigger things if this simply parts has holes in it.
Two other things is the endl function and cin.get() what do these do as well?
int main()
{
int input = 0;
do
{
cout<<"Enter a number (-1 = QUIT):";
if (!(cin>> input))
{
cout<<"INVALID" <<endl;
cin.clear();
cin.ignore(10000, '\n');
}
if (input != -1)
{
cout<<input<<" was entered"<<endl;
}
}
while (input != -1);
cout<<"Done"<<endl;
cin.get();
return 0;
}
The code below is the code provided in the question as I write this, except I've added the requisite headers and using directive at the top:
#include <iostream>
using namespace std;
int main()
{
int input = 0;
do
{
cout<<"Enter a number (-1 = QUIT):";
if (!(cin>> input))
{
cout<<"INVALID" <<endl;
cin.clear();
cin.ignore(10000, '\n');
}
if (input != -1)
{
cout<<input<<" was entered"<<endl;
}
}
while (input != -1);
cout<<"Done"<<endl;
cin.get();
return 0;
}
#include <iostream>
is a preprocessor directive. The source code preprocessor is run before the compiler proper, and performs text substitution, text inclusion and text selection. The #include directs it to include all the text from a header called iostream. The angle brackets, as opposed to double-quote characters, says that it shouldn't bother to search in the including file's directory. Well actually it's unspecified what extra search it shouldn't do, but in practice, with current compilers, it's as described.
The iostream header provides declarations of i/o stuff from the standard library, such as std::cout.
using namespace std;
makes the identifiers from the std namespace available directly in the global namespace. Meaning you can write, for example, just cout instead of qualified std::cout or fully qualified ::std::cout.
A using namespace directive is practical for small exploratory and personal tool programs, but can be more troublesome in larger code base.
Anyway, remember to NEVER put such directive in the global namespace in a header, because that's a sure way to create name collisions in code that includes that header. As an example, the standard library defines a name std::distance. Without the qualification, with a using namespace std; directive, the name distance is very likely to collide with a name distance in using code.
int main()
is the minimal declaration of main. The main function was the user-provided startup function in C, and in C++ it serves roughly the same purpose, except that in C++ dynamic initialization of static variables can happen before main is executed.
The declaration above is the C++03 way. In C++11 it can alternatively be declared as
auto main() -> int
which means exactly the same, and which is a bit more verbose, but can be reasonable to indicate a convention of using this syntax in general. I.e. for consistency.
The main function can also have arguments, which then represent the command line arguments provided to the process, but this scheme only works well in UTF-8 based *nix-es. For the main arguments are char-based, and the default char-based text encoding in Windows is such that e.g. filenames with international characters can't be represented. Thus, it's not a generally good idea to use the main arguments for portable code.
int input = 0;
declares a variable called input, of type int, and initializes it to 0.
Any zero value of a fundamental type represents false when it's used as a boolean. Conversely, any non-zero value represents true, and this convention stems from early C, which didn't have a bool type. In modern C++ it's better to use the bool type for booleans, with the values (literally) false and true.
The variable above, however, is not used as a boolean, but represents the last number input by the user.
do
{
// Stuff, called the "loop body".
}
while (input != -1);
This is a do-while loop. The continuation condition stated after the while is checked after each iteration. Which means that the loop body is guaranteed to be executed at least once.
C++ has three other loops: the while loop; the ordinary for-loop, which collects all the loop control stuff in the loop head; and the range-based for, which is especially nice for iterating over the items in a collection.
cout<<"Enter a number (-1 = QUIT):";
if (!(cin>> input))
{
cout<<"INVALID" <<endl;
cin.clear();
cin.ignore(10000, '\n');
}
The first statement above just prompts the user. The cout and cin streams are synchronized, so that when the subsequent input operation is attempted, the output, if not already presented on the screen, is flushed. Instead of such automatic, implicit flushing, you can guarantee a flush by doing it explicitly, like this:
cout<<"Enter a number (-1 = QUIT):" << flush;
The expression cin >> input
attempts to interpret the next "word" of user input as an integer, and store that in the variable input, and
produces a reference to cin as its expression result.
If the input of text fails, or if the conversion from textual specification to int fails, then cin enters a failure state. In this state further input is just ignored. Happily that's easy to check for, because when a stream is used directly as an if or while (including do-while) condition, then it converts implicitly to boolean as if you had written !stream.fail().
Hence, !(cin >> input) does all of the above, and produces the result of !!cin.fail() (twice negated, “not not”), where fail is a member function that check whether the stream is in a failure state.
If the stream is in a failure state, then that state must be cleared, lest further input operations will all be ignored, and that's what
cin.clear();
achieves.
In addition there will be some input text – at the least a newline (end of line marker) – left in the input buffer, and to avoid that text being processed as valid input the next time around the loop, it should better be removed! And that's what the
cin.ignore(10000, '\n');
accomplished. Under the assumption that there's not more than 10000 characters left in the input buffer…
cout<<"INVALID" <<endl;
Outputs the text “INVALID” followed by a newline. Outputting the endl manipulator has the effect of a newline plus a flush. Thus the above is equivalent to and just short for
cout<<"INVALID\n" << flush;
It often happens that newbies are concerned with the lack of efficiency of endl as opposed to just \n. This concern is however misplaced. Iostreams are for convenience and (due to stronger type checking) avoiding the easy bugs of C style i/o; they're generally not what one would choose for efficiency.
After the loop, the
cout<<"Done"<<endl;
cin.get();
stops the program until the user enters some input.
This is because when the program is run from an IDE (as opposed to from the command line), the console window could just otherwise disappear. And especially for non-interactive programs that's undesirable. So the statement above, while not needed for this particular program, is a general convention.
However, it's ungood. It becomes very annoying when the program is run from the command line! Instead, to see all the output of a program, do either
run it from the command line, or
run it in a way that automatically stops at the end (e.g. Ctrl+F5 in Visual Studio), or
place a breakpoint at the last } right curly brace of main, and run it in the debugger.
return 0;
is unnecessary, since this is the default function result for main (main is unique in having a default function result).
The value returned from main will in practice become a process exit code.
In both Windows and *nix the convention is that 0 means success and any other value means failure.
In C++ the only portable values are 0, EXIT_FAILURE and EXIT_SUCCESS, where the latter two come from the stdlib.h header. EXIT_FAILURE and EXIT_SUCCESS depend on the system at hand, but the latter is typically just 0. In Windows you may want to use Windows' own E_FAIL instead of EXIT_FAILURE, because (for unfathomable reasons) Windows C++ compilers typically define EXIT_FAILURE as 1, which is also a specific Windows error code – and in Windows the process exit code is typically literally what that term indicates, namely a standard error code, with 0 as “no error”.

C++: cin.peek(), cin >> char, cin.get(char)

I've got this code with use of cin.peek() method. I noticed strange behaviour, when input to program looks like qwertyu$[Enter] everything works fine, but when it looks like qwerty[Enter]$ it works only when I type double dollar sign qwerty[Enter]$$. On the other hand when I use cin.get(char) everything works also fine.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
char ch;
int count = 0;
while ( cin.peek() != '$' )
{
cin >> ch; //cin.get(ch);
count++;
}
cout << count << " liter(a/y)\n";
system("pause");
return 0;
}
//Input:
// qwerty$<Enter> It's ok
//////////////////////////
//qwerty<Enter>
//$ Doesn't work
/////////////////////////////
//qwerty<Enter>
//$$ works(?)
It's because your program won't get input from the console until the user presses the ENTER key (and then it won't see anything typed on the next line until ENTER is pressed again, and so on). This is normal behavior, there's nothing you can do about it. If you want more control, create a UI.
Honestly I don't think the currently accepted answer is that good.
Hmm looking at it again I think since, operator<< is a formatted input command, and get() a plain binary, the formatted version could be waiting for more input than one character to do some formatting magic.
I presume it is way more complicated than get() if you look what it can do. I think >> will hang until it is absolutely sure it read a char according to all the flags set, and then will return. Hence it can wait for more input than just one character. For example you can specify skipws.
It clearly would need to peek into more than once character of input to get a char from \t\t\t test.
I think get() is unaffected by such flags and will just extract a character from a string, that is why it is easier for get() to behave in non-blocking fashion.
The reason why consider the currently accepted answer wrong is because it states that the program will not get any input until [enter] or some other flush-like thing. In my opinion this is obviously not the case since get() version works. Why would it, if it did not get the input?
It probably still can block due to buffering, but I think it far less likely, and it is not the case in your example.