Float64 to string - c++

In C++, how can I convert a data of type float64 to a string without losing any of the data in float64? I need it to not only be converted to a string, but add a string to either side of the number and then sent to be written in a file.
Code:
string cycle("---NEW CYCLE ");
cycle+=//convert float64 to string and add to cycle
cycle+= "---\r\n";
writeText(cycle.c_str()); //writes string to txt file
Thanks.

The usual way of converting numbers to std::strings is to use std::ostringstream.
std::string stringify(float value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}
// [...]
cycle += stringify(data);

You should use sprintf. See documentation here C++ Reference.
As an example it would be something like:
char str[30];
float flt = 2.4567F;
sprintf(str, "%.4g", flt );
Also I would use string::append to add the string. See here .
UPDATE
Updated code according to comment.

You can use sprintf to format the string.

Related

In c++, how do you get the input of a string, float and integer from 1 line?

An input file is entered with the following data:
Juan Dela Cruz 150.50 5
'Juan Dela Cruz' is a name that I would like to assign to string A,
'150.50' is a number I would like to assign to float B
and 5 is a number I would like to assign to int C.
If I try cin, it is delimited by the spaces in between.
If I use getline, it's getting the whole line as a string.
What would be the correct syntax for this?
If we analyze the string, then we can make the following observation. At the very end, we have an integer. In front of the integer we have a space. And in front of that the float value. And again in fron of that a space.
So, we can simply look from the back of the string for the 2nd last space. This can easily be achieved by
size_t position = lineFromeFile.rfind(' ', lineFromeFile.rfind(' ')-1);
We need a nested statement of rfind please see here, version no 3.
Then we build a substring with the name. From start of the string up to the found position.
For the numbers, we put the rest of the original string into an std::istringstream and then simply extract from there.
Please see the following simple code, which has just a few lines of code.
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>
int main() {
// This is the string that we read via getline or whatever
std::string lineFromeFile("Juan Dela Cruz 150.50 5");
// Let's search for the 2nd last space
size_t position = lineFromeFile.rfind(' ', lineFromeFile.rfind(' ')-1);
// Get the name as a substring from the original string
std::string name = lineFromeFile.substr(0, position);
// Put the numbers in a istringstream for better extraction
std::istringstream iss(lineFromeFile.substr(position));
// Get the rest of the values
float fValue;
int iValue;
iss >> fValue >> iValue;
// Show result to use
std::cout << "\nName:\t" << name << "\nFloat:\t" << fValue << "\nInt:\t" << iValue << '\n';
return 0;
}
Probably simplest in this case would be to read whole line into string and then parse it with regex:
const std::regex reg("\\s*(\\S.*)\\s+(\\d+(\\.\\d+)?)\\s+(\\d+)\\s*");
std::smatch match;
if (std::regex_match( input, match, reg)) {
auto A = match[1];
auto B = std::stof( match[2] );
auto C = std::stoi( match[4] );
} else {
// error invalid format
}
Live example
As always when the input does not (or sometimes does not) match a strict enough syntax, read the whole line and then apply the rules which to a human are "obvious".
In this case (quoting comment by john):
Read the whole string as a single line. Then analyze the string to work out where the breaks are between A, B and C. Then convert each part to the type you require.
Specifically, you probably want to use reverse searching functions (e.g. https://en.cppreference.com/w/cpp/string/byte/strrchr ), because the last parts of the input seem the most strictly formatted, i.e. easiest to parse. The rest is then the unpredictable part at the start.
either try inputting the different data type in different lines and then use line breaks to input different data types or use the distinction to differentiate different data types like adding a . or comma
use the same symbol after each data package, for example, Juan Dela Cruz;150.50;5 then you can check for a ; and separate your string there.
If you want to use the same input format you could use digits as an indicator to separate them

Writing normal C++ String to Rapid JSON is resulting in string with backslash

string str = {"appId":"com.mymusic.app","Connectivity":True,"DistractionLevel":2,"display":True};
if(!str.empty())
{
StringBuffer bf;
PrettyWriter<StringBuffer> writer (bf);
writer.StartObject();
writer.Key("info"));
writer.String(str.c_str());
writer.EndObject();
cout<<"request string is:" , (char *)bf.GetString());
}
cout is printing the below line with back slash
{"info":"\"appId\":\"com.mymusic.app\",\"checkConnectivity\":True,\"driverDistractionLevel\":2,\"display\":True}"}
What i was expecting is
{"info": {"appId":"com.mymusic.app","Connectivity":True,"DistractionLevel":2,"display":True} }
You are using the the wrong function. The String function will add a string value to the json-object and in this context the escaping of " to \" is expected.
I think what you actually want to do is add the string as a json-sub-object. From what I found in the rapidjson documentation the function you want to use for that is RawValue.

C++ fstream - problems reading only certain variable types

I am using fstream to read a notepad file containing numerical data. I am using dynamic memory allocation and the data is type float.
However there is rouge data in form of characters in my file - how would I write code that searches for and ignores the characters in the file, and only reads in the numbers?
I am assuming I will need to use either ignore or peek?
fstream myfile("data1");
myfile.ignore ();
or myfile.peek ();
But am a bit unsure. Any help is appreciated!
If it has always this format, the words and numbers are separated by whitespace, you can simply read it one string at a time and let a std::istringstream do the parsing. When this fails, you know it is not a number
std::string word;
while (myfile >> word) {
std::istringstream is(word);
double d;
if (is >> d) {
// found a number
std::cout << d << '\n';
} else {
// something's wrong
std::cerr << word << '\n';
}
}
Update:
Due to popular demand: a stringstream works like any other stream (std::cin, std::cout or std::fstream). The main difference is that a stringstream operates on strings. This means input comes from a string instead of a file or standard input, or output goes to a string, much like it goes to standard output or a file.
Parsing input is like this typically requires that you extract the tokens into a string and
test the content of your string against your parsing requirements. For example, when you extract into the string, you can then run a function which inserts it into a std::stringstream, then extract into the data type you're testing against, and see if it succeeds.
Another option is to check if the string is not a certain string, and convert back to the desired data type if so:
while (f >> str)
{
if (f != "badInput")
{
// convert to double and add to array
}
}
Fortunately you can use the Boost.Regex facilities to avoid having to do most of the work yourself. Here's an example similar to yours:
#include <boost/regex.hpp>
int main()
{
std::fstream f("test.txt");
std::string token;
boost::regex floatingPoint("((\\+|-)?[0-9]+)?(\\.)?([0-9]+)");
while (f >> token)
{
if (boost::regex_match(token, floatingPoint))
{
// convert to double using lexical_cast<> and add to array
}
}
Thanks for the help everybody - But all this seems a bit advanced for someone of my poor capability! We have been suggested to use the following - but am unsure how you would do this to distinguish between words and numbers:
fstream myfile("data1");
myfile.eof ();
myfile.good ();
myfile.fail ();
myfile.clear ();
myfile.ignore ();
myfile.close ();
myfile.peek ();

testing for double in visual c++

I am designing a gui in visual c++ and there is a textbox where user inputs values so a calculation can be performed. How do I validate the input to ensure it can be cast to a double value?
In any C++ environment where you have a std::string field and wish to check if it contains a double, you can simply do something like:
#include <sstream>
std::istringstream iss(string_value);
double double_value;
char trailing_junk;
if (iss >> double_value && !(iss >> trailing_junk))
{
// can use the double...
}
As presented, this will reject things like "1.234q" or "-13 what?" but accept surrounding whitespace e.g. " 3.9E2 ". If you want to reject whitespace, try #include <iomanip> then if (iss >> std::noskipws >> double_value && iss.peek() == EOF) ....
You could also do this using old-style C APIs:
double double_value;
if (sscanf(string_value.c_str(), "%lf%*c", &double_value) == 1)
You cannot "cast" a string to a double, you can only convert it. strtod function will return a pointer to the character within the string where the conversion stopped, so you can decide what to do further. So you can use this function for conversion AND checking.
I'd recommend Boost's lexical_cast, which will throw an exception if the conversion fails.
Since this seems to be a C++ CLI related question and your string from the textbox might be a .NET string, you might want to check the static Double::Parse method. For more portable solutions see the other answers...
As stated already, strtod(3) is the answer.
bool is_double(const char* str) {
char *end = 0;
strtod(str, &end);
// Is the end point of the double the end of string?
return end == str + strlen(str);
}
To address #Ian Goldby's concern, if white space at the end of the sting is a concern, then:
bool is_double(const char* str) {
char *end = 0;
strtod(str, &end);
// Is the end point of the double plus white space the end of string?
return end + strspn(end, " \t\n\r") == str + strlen(str);
}
Simply convert it to a double value. If it succeeds, the input is valid.
Really, you shouldn't be writing your own rules for deciding what is valid. You'll never get exactly the same rules as the library function that will do the actual conversion.
My favourite recipe is to use sscanf(), and check the return value to ensure exactly one field was converted. For extra credit, use a %n parameter to check that no non-whitespace characters were left over.

Getting a unix timestamp as a string in C++

I'm using the function time() in order to get a timestamp in C++, but, after doing so, I need to convert it to a string. I can't use ctime, as I need the timestamp itself (in its 10 character format). Trouble is, I have no idea what form a time_t variable takes, so I don't know what I'm converting it from. cout handles it, so it must be a string of some description, but I have no idea what.
If anyone could help me with this it'd be much appreciated, I'm completely stumped.
Alternately, can you provide the output of ctime to a MySQL datetime field and have it interpreted correctly? I'd still appreciate an answer to the first part of my question for understanding's sake, but this would solve my problem.
time_t is some kind of integer. If cout handles it in the way you want, you can use a std::stringstream to convert it to a string:
std::string timestr(time_t t) {
std::stringstream strm;
strm << t;
return strm.str();
}
I had the same problem. I solved it as follows:
char arcString [32];
std::string strTmp;
// add start-date/start-time
if (strftime (&(arcString [0]), 20, "%Y-%m-%d_%H-%M-%S", (const tm*) (gmtime ((const time_t*) &(sMeasDocName.sStartTime)))) != 0)
{
strTmp = (char*) &(arcString [0]);
}
else
{
strTmp = "1970-01-01_00:00:00";
}
Try sprintf(string_variable, "%d", time) or std::string(itoa(time))?
http://www.codeguru.com/forum/showthread.php?t=231056
In the end time_t is just an integer.