Section 7 - String to Number Conversions
This section has some useful review material from CS 2A regarding conversions between strings and numbers. Also, you'll find some "avoid point loss" hints at the end.
2B.7.1 Converting From Strings to Numbers
In beginning C++ classes, students often use the cin statement to read numbers directly from the user console into their int, float or double variables. That is, you often read numbers directly from the user into numeric variables. However in real applications, this is rarely the case. Normally programs read numbers from the user in the form of a string, so if we asked the user for a float or double, and they typed in "-3.4", we would receive that value as a string, and we would be unable to compute with it.
To convert it to a number that we can use for computation, use the simple notation:
istringstream(s) >> c; // convert String s to double c
We would do this, for instance, if we read a user response into the string object s and needed to convert it to a number in order to compute with it. This can be done if c is a double, float, int, long, etc.
2B.7.2 Converting From Numbers to Strings
The other direction requires three statements:
ostringstream cnvrt; cnvrt << c; s = cnvrt.str();
This results in any numeric variable c having its value turned into a string and stored in s. Also, if you have to effect a conversion from number to string twice or more in a program, you must use a separate ostringstream object in place of cnvrt. For instance you could use the name cnvrt2 for the second conversion, cnvrt3 for the third, etc. We will see this below.
2B.7.3 An Example
Here is an example to demonstrate the conversion. Note that, in addition to <iostream> and <string> we have to #include the file <sstream>. This is used for the conversions to work.
#include <iostream> #include <string> #include <sstream> using namespace std; int main() { string strMyNum = "123.456"; double numMyNum; // used to convert a string to any numeric type istringstream(strMyNum) >> numMyNum; // these should be the same if conversion worked cout << "Original value as string: " << strMyNum << endl << "Original value as number: " << numMyNum << endl; // compute using the number numMyNum = (numMyNum + 1) / (numMyNum - 1); // used to convert any numeric type to a string ostringstream cnvrt; cnvrt << numMyNum; strMyNum = cnvrt.str(); // these should be the same if conversion worked cout << "Answer as string: " << strMyNum << endl << "Answer as number: " << numMyNum << endl; numMyNum = (numMyNum + 1) / (numMyNum - 1); ostringstream cnvrt2; cnvrt2 << numMyNum; strMyNum = cnvrt2.str(); // convert from double c to string s // these should be the same if conversion worked cout << "Answer as string: " << strMyNum << endl << "Answer as number: " << numMyNum << endl; }
Here is your output:

This is an interesting mathematical result, by the way (unrelated to our course). We used the formula (x+1)/(x-1) to get a second number. Then we applied it again, and we got the original number back! Does anyone know anything about this?
2B.7.4 Testing for Non-Numeric Input
If you are asked to get a number from the user in this course, you can usually assume that the user gives you a real number, and not something illegal, like "dork" or "five". You are not expected to inspect the string for valid characters. If you come up with a complicated algorithm for doing this that makes your code hard to read, I'll probably deduct points, so don't try to protect against non-numeric input.
Typically, it is not that easy to check a string and determine if the entire string is a valid number.
However, there is one thing you can do that is not too hard. Using the above techniques, you can see if the beginning of the string can be interpreted as a number. For example, the following strings begin with valid numbers:
- "123.455" → 123.455
- "-87 → -87
- " 234 " → 234
- "5Hello There" → 5
- "54.32Hello There" → 54.32
- "123.123.123.123" → 123.123
If you want a number in this course, you can usually assume the user enters a number. But if you want to test this, you can do it by checking the expression istringstream(s) >> c to see if it is true (the string starts with a number) or false (it does not):
if ( istringstream(user_string) >> num ) cout << "Yes, I was able to convert the first part to the number: "<< num << endl; else cout << "No, " << user_string << " begins with non-numeric content. " << endl;
In short, the value of the expression A >> B when you are doing a string conversion will be true if the conversion was successful. Here is a full program that demonstrates it:
#include <iostream> #include <string> #include <sstream> using namespace std; int main() { string user_string; double num; // these should be the same if conversion worked cout << "Type in something and I'll tell you if " "\nthe first part can be converted to a number: "; // compute using the number getline(cin, user_string); if ( istringstream(user_string) >> num ) cout << "Yes, I was able to convert the first part to the number: " << num << endl; else cout << "No, " << user_string << " begins with non-numeric content. " << endl; return 0; }
I'll let you run this with different input to see how it works.
Prevent Point Loss
- Do not use ASCII or UNICODE. When you need a char constant in your program, do not use numbers, such as 65 or 57 which are meaningless to programmers. Instead use understandable chars like 'A' or '9' instead. In addition to being more readable and less error-prone, this rule makes your job easier. (1 - 2 point penalty)
- Write to spec. Don't change the names or purpose of program variables, methods or output. Write your program so that it does exactly what is asked, not sort-of or an enhanced version of the assignment. (4 - 12 point penalty)
- Don't duplicate logic. If you have one method (function), such as set() or checkVal(), that does error checking, call that method from others that need the error checking, don't rewrite the error checking code in two places. If you have the same code in two places, consider making a separate method (function) out of that code and calling that method from those two places. (1 - 2 point penalty)
- Use member names directly from instance or static methods (like socSecNum) - do not use accessors from inside those methods (like getSocSecNum()) as it is unnecessary. (1 - 2 point penalty)
- Use loops on arrays. Do not have a sequence of practically identical statements, like somArray[0] = ...xyz, somArray[1] = ...xyz, somArray[2] = xyz. ..., that involve literal (constant) indexes. Use one statement, with a variable index, like somArray[k] = xyz inside a loop. .(2 - 3 point penalty)
This has been a fun introduction to your second C++ computer science course. In the next 11 weeks you will become seriously capable C++ programmers. I hope that you enjoy the ride.