I've been assigned a problem I simply do not understand. I know that I need to use a cin function (like cin.get()), but I'm not sure which one I need or how to use it in this circumstance.
I need to create an insertion and extraction operator that reads (and writes) 3 pieces of data. All of the data is of the type int. For context, the data is the whole part of a fraction, the numerator, and the denominator. The data needs to be delimited by spaces, and the operators will be used for file input and output.
What I really want to know is which cin function I should use, and what the particular syntax should be considering I want to store the value in an integer.
Thanks in advance!
With cin, you can just read data using something like this:
int wholepart,numer,denom;
cin>>wholepart>>numer>>denom;
This would read 3 integers into wholepart, numer and denom respectively. It will skip over whitespace separating the integers.
The normal operator>> for ints expects the data to be separated by whitespace, so you should be able to just use it and interpret the results as you see fit.
Related
I need to store data into two arrays that are stored in the order Name then Number
Ex:
Kara
000131012
Tucker
002102000
I understand how to use the single-line method:
while (infile >> a >> b)
{
// process pair (a,b)
}
But this doesn't work for the way this data is stored.
I am not sure how sensible it is to add an answer so late (and to this easy question), but I want to be clear since there were some missunderstandings in the comments.
How does >> work?
The operator>> first discards als leading space characters (spaces, tabs, newlines, maybe more, this depends on the locale). Then it will try to read as many non-whitespace characters as possible (so int i; cin >> i; with input 123123jj sets i to 123123). Then it will potentially set the failbit, eofbit, or badbit, which influence the boolean value of the stream.
What does that mean for your code?
If your names consistenly do not include a space character, your code will run perfectly completely independent of the number of words per line. If you have that guarantee of spaceless names, I would recommend this way since it is easy and you don't get a problem if your input is a bit faulty and has for example a double newline at some point.
If you have perhaps spaces in the names, your code above will fail. Then you have to use std::getline. Its usage is well documented on the linked page.
In the textbook "Starting Out In C++" by Gaddis in chapter 1 the author says that some numbers like zip codes are intended for humans to read, to be printed out on the screen to look at and to not calculate with so they should be stored in string data type not numeric data types. But there is a couple of other reasons why this statement is true. The only other reason why I can think this would be true is if you were to enter a zip code with an ending like 37217-1221 you may have to use string catenation to only use the first five digits chopping of the characters after the -1221. What would be some other reasons for the statement "If a number is not going to be used in an arithmetic operation, store it in a string data type". Any answers would be greatly appreciated.
Zipcodes simply are not numeric data. As you point out, zipcodes can contain extensions, which numeric data does not represent. They can also contain significant leading zeros. Some postal code schemes can also contain letters.
Your questions was a bit...not of a questions? That's the best I can explain it. Anyway, a string is text and an integer or number is numerical and should only be used for calculations or counting. For example:
A zip code is a number but you will never do calculations with it. A zip code is something you reference as a place and has no counting purpose. If you think this could confuse you later on try to give the variable with the zip code an assignment of a String so that you cannot try to do any sort of math with the variable.
I read an integer number :
is >> myInteger;
Now I want to know how many digits were read (I'm talking of the possible leading zeros). How can I do that?
You can:
get the value as a string, then parse it separately, however you wish (check length, count zeros, etc).
use is.tellg for this; Keep in mind that tellg will give you buffer positions, not not what was at those positions (it could be space characters or zeros)
read the buffer character by character using is.get, then process values according to your needs.
You could get the value of is.tellg() before you stream in the integer, then get it again and find the difference.
EDIT: Although as pointed out in the comments that will just tell you how many elements of the stream were consumed, some of which may be whitespace.
I am trying to read some characters that satisfy certain condition from stdin with iostream library while leave those not satisfying the condition in stdin so that those skipped characters can be read later. Is it possible?
For example, I want characters in a-c only and the input stream is abdddcxa.
First read in all characters in a-c - abca; after this input finished, start read the remaining characters dddx. (This two inputs can't happen simultaneously. They might be in two different functions).
Wouldn't it be simpler to read everything, then split the input into the two parts you need and finally send each part to the function that needs to process it?
Keeping the data in the stdin buffer is akin to using globals, it makes your program harder to understand and leaves the risk of other code (or the user) changing what is in the buffer while you process it.
On the other hand, dividing your program into "the part that reads the data", "the part that parses the data and divides the workload" and the "part that does the work" makes for a better structured program which is easy to understand and test.
You can probably use regex to do the actual split.
What you're asking for is the putback method (for more details see: http://www.cplusplus.com/reference/istream/istream/putback/). You would have to read everything, filter the part that you don't want to keep out, and put it back into the stream. So for instance:
cin >> myString;
// Do stuff to fill putbackBuf[] with characters in reverse order to be put back
pPutbackBuf = &putbackBuf[0];
do{
cin.putback(*(pPutbackBuf++));
while(*pPutbackBuf);
Another solution (which is not exactly what you're asking for) would be to split the input into two strings and then feed the "non-inputted" string into a stringstream and pass that to whatever function needs to do something with the rest of the characters.
What you want to do is not possible in general; ungetc and putback exist, but they're not guaranteed to work for more than one character. They don't actually change stdin; they just push back on an input buffer.
What you could do instead is to explicitly keep a buffer of your own, by reading the input into a string and processing that string. Streams don't let you safely rewind in many cases, though.
No, random access is not possible for streams (except for fstream an stringstream). You will have to read in the whole line/input and process the resulting string (which you could, however, do using iostreams/std::stringstream if you think it is the best tool for that -- I don't think that but iostreams gurus may differ).
I have a c++ program, I would like the first argument of the main (argv[1]) to correspond to a table of float. Is it possible to do that??
I was thinking about putting in a string my floats separated with spaces (e.g. "1.12 3.23 4.32 1.1 ...")
Is there a way to automatically convert such a string into a table of floats? If I understand well the atof function converts a string into a double. So it seems it could be possible to split my string using the spaces and then convert each portion using atof.
This option does not seem to be very efficient to me? In addition it returns double and not float :(
So, is there a better way to pass table of float as argument of a c++ program ?
Thank you
A stringstream can do both the splitting at spaces and the parsing into a float.
std::stringstream ss(the_string);
std::vector<float> v(std::istream_iterator<float>(ss),
(std::istream_iterator<float>()));
// the extra parentheses here are ugly but necessary :(
How to obtain the string with the data depends on how large it is and where it is supposed to come from. Just keep in mind that in many systems the arguments passed to program are already split by spaces, putting each part in a different element of argv.
Save it in a text file, and then read it from the file when your program starts. I isn't worth it to pass it as a command-line argument.
The main() parameter list is as it is. You can pass the strings of your numbers as arguments to your program. The main function will have to parse its argument.
When you want to pass a space separated list of numbers in argv[1] you can use the strtok function to get the individual number strings and have to pass it to a conversion function.
When your conversion function returns a double you should check that the result can be represented by a float and cast the value to a float variable. But I would consider to use double as the internal representation.
In addition to Singer's answer:
The commandline should be used mainly by human, not computer. If you really need a table of values, use configuration file. You can always use human readable format for it.