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

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”.

Related

using input redirection in while loop

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.

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.

Reading with setw: to eof or not to eof?

Consider the following simple example
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main() {
string str = "string";
istringstream is(str);
is >> setw(6) >> str;
return is.eof();
}
At the first sight, since the explicit width is specified by the setw manipulator, I'd expect the >> operator to finish reading the string after successfully extracting the requested number of characters from the input stream. I don't see any immediate reason for it to try to extract the seventh character, which means that I don't expect the stream to enter eof state.
When I run this example under MSVC++, it works as I expect it to: the stream remains in good state after reading. However, in GCC the behavior is different: the stream ends up in eof state.
The language standard, it gives the following list of completion conditions for this version of >> operator
n characters are stored;
end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.
Given the above, I don't see any reason for the >> operator to drive the stream into the eof state in the above code.
However, this is what the >> operator implementation in GCC library looks like
...
__int_type __c = __in.rdbuf()->sgetc();
while (__extracted < __n
&& !_Traits::eq_int_type(__c, __eof)
&& !__ct.is(__ctype_base::space,
_Traits::to_char_type(__c)))
{
if (__len == sizeof(__buf) / sizeof(_CharT))
{
__str.append(__buf, sizeof(__buf) / sizeof(_CharT));
__len = 0;
}
__buf[__len++] = _Traits::to_char_type(__c);
++__extracted;
__c = __in.rdbuf()->snextc();
}
__str.append(__buf, __len);
if (_Traits::eq_int_type(__c, __eof))
__err |= __ios_base::eofbit;
__in.width(0);
...
As you can see, at the end of each successful iteration, it attempts to prepare the next __c character for the next iteration, even though the next iteration might never occur. And after the cycle it analyzes the last value of that __c character and sets the eofbit accordingly.
So, my question is: triggering the eof stream state in the above situation, as GCC does - is it legal from the standard point of view? I don't see it explicitly specified in the document. Is both MSVC's and GCC's behavior compliant? Or is only one of them behaving correctly?
The definition for that particular operator>> is not relevant to the setting of the eofbit, as it only describes when the operation terminates, but not what triggers a particular bit.
The description for the eofbit in the standard (draft) says:
eofbit - indicates that an input operation reached the end of an input sequence;
I guess here it depends on how you want to interpret "reached". Note that gcc implementation correctly does not set failbit, which is defined as
failbit - indicates that an input operation failed to read the expected characters, or
that an output operation failed to generate the desired characters.
So I think eofbit does not necessarily mean that the end of file impeded the extractions of any new characters, just that the end of file has been "reached".
I can't seem to find a more accurate description for "reached", so I guess that would be implementation defined. If this logic is correct, then both MSVC and gcc behaviors are correct.
EDIT: In particular, it seems that eofbit gets set when sgetc() would return eof. This is described both in the istreambuf_iterator section and in the basic_istream::sentry section. So now the question is: when is the current position of the stream allowed to advance?
FINAL EDIT: It turns out that probably g++ has the correct behavior.
Every character scan passes through <locale>, in order to allow different character sets, money formats, time descriptions and number formats to be parsed. While there does not seem to be a through description on how the operator>> works for strings, there are very specific descriptions on how do_get functions for numbers, time and money are supposed to operate. You can find them from page 687 of the draft forward.
All of these start off by reading a ctype (the "global" version of a character, as read through locales) from a istreambuf_iterator (for numbers, you can find the call definitions at page 1018 of the draft). Then the ctype is processed, and finally the iterator is advanced.
So, in general, this requires the internal iterator to always point to the next character after the last one read; if that was not the case you could in theory extract more than you wanted:
string str = "strin1";
istringstream is(str);
is >> setw(6) >> str;
int x;
is >> x;
If the current character for is after the extraction for str was not on the eof, then the standard would require that x gets the value 1, since for numeric extraction the standard explicitly requires that the iterator is advanced after the first read.
Since this does not make much sense, and given that all complex extractions described in the standard behave in the same way, it makes sense that for strings the same would happen. Thus, as the pointer for is after reading 6 characters falls on the eof, the eofbit needs to be set.

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.

c++ isalnum endless loop

Greetings!
Lets cut the excessive intro this time and get straight to the point.
I have a problem in C++ using the isalnum method.
the code:
int playAgainst = 0;
do
{
cout << "Who do you want to play against?(1/2)\n";
cout << "1: Human player\n";
cout << "2: Computer player\n";
cin >> playAgainst
} while(!isalnum(playAgainst) && playAgainst != 0);
As seen in the code, I'm providing the user with a choice. Play against human or play against a computer.
What I want is, as long as the user enters anything else then an integer value(cin >> playAgainst) to repeat the question. However, If i enter a char, or string value, it keeps looping endlessly. I am not 100% sure, but it would be obvious, if the problem is, that the non int value is already saved as the value for playAgainst.. How can I check in this bit of code if the input value is int before saving it?
Or is the only possibility to save as a char/string and then check?
If the latter is the case, a new problem arises. isalnum only accepts int as parameter, atleast from what I know. How will I check if that string or char is an int?
Thank you for taking the time to read. And hopefully Ill be accepting a reply as answer soon ^^
Thanks everyone for the answers.
I have gotten what I wanted, and everything has been solved.
The reason I chose for the accepted answer, is well... because initially, it made my code work the way I want it to. I want to accept multiple answers though..
Make playAgainst a char and compare against '0', not 0. Right now, the user has to enter the ASCII (or whatever your character set is) code for the character '1' or '2'.
isalnum won't work on ints outside the valid range of char, except for EOF. (The fact that it takes an int argument is a leftover from C, which has different integer promotions rules than C++. to accomodate for EOF.)
Remove the isalnum() check. cin >> playAgainst will convert anything except a number to zero, which will be caught by the second check. Note that this is only an option because zero is not a valid input.
isalnum() is useful if you're interpreting the characters yourself, but in this case the stream has already done that for you.
This is how the compiler will implement isalnum:
int isalnum (int ch)
{
return (ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9');
}
So you might as well write that code snippet in your own code, and it will be equivalent with an inlined version of isalnum.
It's because you don't clear the buffer. When the input is invalid, you need to clear it from the buffer, and then you can move on to the next input, else you're trying to extract the same input every time (which fails, because it's the same bad input), and thus enter an infinite loop.
The problem is that you're inputing an int, and not a char. And if the
text in the input isn't an int, then the input fails. In which case,
playAgainst isn't modified, and the failure is memorized in std::cin
until you explicitly clear the error. And inputting from a stream in an
error state is a no-op. What you probably want to do is
Input a single character: if you don't want to skip spaces, using
`std::cin.get( ch )` or `ch = std::cin.get()`. (In the latter
case, `ch` should be an `int`, since it must also handle `EOF`.
On the other hand, you can use `::isalnum` on it directly, which
you can't do if `ch` is a `char`.
Fully check for valid input: not just `::isalnum`, but rather
whether the input is a legal selector in your list. Something
along the lines of:
ch != EOF && std::find( legalChars.begin(), legalChars.end(), (char)ch ) != legalChars.end()
In case of error, clear any remaining input, say with:
std::cin.ignore(INT_MAX, '\n');
In practice, you'll probably want to treat EOF differently from
an erroneous command. (If you don't clear the input after EOF, you
won't be able to read anything else. But presumably, if you got EOF,
it's because the user gave up, and doesn't want to try any more.)
Finally, it's probably preferrable to keep all of the information in
a common location, using a table of:
struct Command
{
char op;
char const* prompt;
void (* func)();
};
You then loop over a table of these to output the prompt, search it to
see if the character was legal, and finally, call the function on the
entry you found. Or define an abstract base class, a concrete class
deriving from it for each command, and use an std::map<char,
AbstractBase*> for the mapping, etc. Very C++, but perhaps a bit
overkill for such a simple case.
Why not use isdigit().