Input string C++ double chevron - c++

I'm currently trying to use a double chevron in a string for "<<" and ">>" to represent bit shifting. However, my program does not seem to recognize using double chevrons for any input. If I change it to any other string, it works perfectly.
derpleft will work, however "<<" will not work.
keywords_["derpleft"] = keywords_["<<"] = make<BitShiftLeft>();
keywords_["derpright"] = keywords_[">>"] = make<BitShiftRight>();
dictionary_type keywords_;
typedef std::map<string_type,Token::pointer_type> dictionary_type;
typedef std::string string_type;

I just don't understand this statement:
keywords_["derpleft"] = keywords_["<<"] = make<BitShiftLeft>();
It seems you want << and derpleft to point to (store) the value returned by make<BitShiftLeft> call. In that case, why not simply it as follows:
keywords_["derpleft"] = make<BitShiftLeft>();
keywords_["<<"] = make<BitShiftLeft>();
You may store the value of make call in some local variable (auto keyword preferred).
And most importantly, you did not mention what the problem is!

I forgot to close this thread, but the issue was I did not set a boolean to true in one of my editor functions. It was simply a logic error that I created.

Related

Matlab regex ${numberFun($4)} - Undefined function 'numberFun' for input arguments of type 'char'

I read that in Matlab it is possible to include a function call inside a regex transformation like this $1double$2[${doubleTextNumber($4)}], assuming 1, 2, 3 to be some regex groups, and 4 to be a purely numeric group. The exact thing I want to do is to catch all arrays consisting of the type creal_T, replace the type with double and double the length of the array.
codeText = "typedef struct {
double tolRob;
creal_T Mt2o[704];
creal_T Ho2o[704];
creal_T Ht2t[704];
creal_T Zo2t[704];
creal_T Ztd[64];
} testType;"
So, I want the struct above to become:
typedef struct {
double tolRob;
double Mt2o[1408];
double Ho2o[1408];
double Ht2t[1408];
double Zo2t[1408];
double Ztd[128];
} SpdEstType;
In Matlab I have made a function to convert a number to text and double it:
function [doubleValue] = doubleTextNumber(inputNumber)
doubleValue = string(str2double(inputNumber)*2.0);
end
I also have a regex that I expect would find the number in each declaration and feed it to the function:
resultString = regexprep(
codeText,
'(?m)^(\W*)creal_T(\s*\w*)(\[([^\]]*\d+)\])',
"$1double$2[${doubleTextNumber($4)}]");
However, as I run this peace of code, Matlab gives me the following error msg:
Error using regexprep
Evaluation of 'doubleTextNumber($4)' failed:
Undefined function 'doubleTextNumber' for input arguments of type 'char'.
As far as I understand, I have made the method do conversion from char, and expect it also to accept this value from my regex. I have tested that it works when I input '704' or "704" directly, and also that the regex works appart from this insertion.
Why does not Matlab find the function from my regex? (they are in the same m file)
It looks like I had 3 issues with my original approach:
In order for regexprep() to recognize my function, it had to be moved to its own m-file. Simply calling a method from inside the same file did not work.
I was using https://regex101.com/ to edit the search expression, but even though it seemed to be selecting the number inside the brackets, group 4 did not get populated by regexprep() in Matlab. A new version did work, and populated group 3 with the numbers I wanted: (?m)^(\W*)creal_T(\s*\w*).([^\]]*\d*)\]
I also added more conversion options to my multiplication method in case the input was a combination of numbers and char arrays.
The final version of my regex call becomes:
resultString = regexprep(
codeText,
'(?m)^(\W*)creal_T(\s*\w*).([^\]]*\d*)\]',
"$1double$2[${multiplyTextNumbers($3,2)}]");
where multiplyTextNumbers() is defined in its own m file as
function [productText] = multiplyTextNumbers(inputFactorText1,inputFactorText2)
%MULTIPLY This method takes numbers as input, and acepts either string,
%char or double or any combination of the three. Returns a string with the
%resulting product.
if (isstring(inputFactorText1) || ischar(inputFactorText1))
inputFactor1 = str2double(inputFactorText1);
else
inputFactor1 = inputFactorText1;
end
if (isstring(inputFactorText2) || ischar(inputFactorText2))
inputFactor2 = str2double(inputFactorText2);
else
inputFactor2 = inputFactorText2;
end
productText = sprintf('%d',inputFactor1*inputFactor2);
end
Hope this can be helpefull to others facing similar issues.

Is extracting formatted input from std::cin with a single line of code possible?

Say I have a function compute_number(float k); and in my program, I need to call this function once with some user input as the argument. The intuitive way to achieve formatted input, would be:
int main()
{
...
float input_numbr;
std::cin >> input_numbr;
compute_number(input_numbr);
...
}
The problem with this, though, is that I've declared and used an extra variable float input_numbr which I'll never use again. I think that's a waste.
So my question is if there's any way to reduce these three lines into one. There must be some way to circumvent the need of creating an additional variable to get one-time formatted keyboard input from an input stream. I'm thinking of something like:
compute_number(cin.get());
The problem with that, however, is that cin.get() does not format the input; it simply returns the ASCII value of whichever character happens to be next in the stream.
So is there a way to call compute_number(cin.next_formatted_input()) like so? Or must one create an additional variable for temporarily holding the formatted cin value.
The problem with this, though, is that I've declared and used an extra variable float input_numbr which I'll never use again. I think that's a waste.
Well, I disagree (advocating for code readability), but here you go:
template<typename T>
T getinput(std::istream& is) {
T result;
is >> result;
return result;
}
should do what you want. You can just write
compute_number(getinput<float>(std::cin));
then. Though a variable is still involved (and needed).

Parameters of GetPrivateProfileInt method

Question: How to use string/char* variable as the path parameter to GetPrivateProfileInt method.
I m trying to use GetPrivateProfileInt given for windows. The following code runs perfeclty without any issue:
int x = GetPrivateProfileInt(L"x",L"y",1,L"This\\is\\the\\path");
But in my case, the path is being passed to the function. Something like this:
void fun(std::string path)
{
//error const char* is incampatible with LPCWSTR.
int x = GetPrivateProfileInt(L"x",L"y",1,path.c_str());
}
In some attempts given below, x is recieving the default value. i.e. the path is not being passed to the GetPrivateProfileInt method correctly.
Following are several other attempts made by me:
Attempt1:
// No error, default value is being read.
int x = GetPrivateProfileInt(L"x",L"y",1,(LPCTSTR)path.c_str());
Attempt2:
// No error, default value is being read.
int x = GetPrivateProfileInt(L"x",L"y",1,(wchar_t*)path.c_str());
Attempt3:
//_T() macro giving error.
// 'Ls' : undeclared identifier.identifier "Ls" is undefined.
LPCTSTR path_s = _T(path.c_str());
int x = GetPrivateProfileInt(L"x",L"y",1,path_s);
I went through the answers here but not able find out the solution.
There are two versions of the function, one takes UCS-2 characters (GetPrivateProfileIntW) and one takes char characters (GetPrivateProfileIntA). There are no versions which allow you to mix the parameters. Your options are to either change the appname and keyname parameters to single-byte to match your data
GetPrivateProfileIntA("x", "y", 1, path.c_str());
or to convert the last parameter to UCS-2 using MultibyteToWideChar, then call GetPrivateProfileIntW.
Pointer-casting is NOT a conversion of the character encoding, and will not work. The compiler type system is there to help you, and making it shut up with a cast is nearly always the wrong thing to do (exception: the return value of GetProcAddress does need a cast).

QSettings does not differentiate between string and int values

I am writing and reading string and int values using a file-backed QSettings object.
When I later try to read the values from a different process, the values are read as strings instead of int.
This is the code I am using to write values:
QSettings settings("TestQSettings.ini", QSettings::IniFormat);
settings.setValue("AAA",QString("111"));
settings.setValue("BBB",222);
This is the file created:
[General]
AAA=111
BBB=222
This is the code I am using to read values:
QVariant qvar = settings.value("AAA");
std::cout << "AAA type " << qvar.type() << std::endl;
qvar = settings.value("BBB");
std::cout << "BBB type " << qvar.type() << std::endl;
If I run this code from the same process:
AAA type 10
BBB type 2
If I run this code from a different process:
AAA type 10
BBB type 10
I know it's possible to convert the types after they have been read.
Unfortunately, this solution will require modifying Windows legacy cross-platform code which I prefer not to modify, for example multiple calls to RegQueryValueEx().
Is it possible to store and read the type information for strings and integers?
For example, Strings will have quotes "" and integers will not:
[General]
AAA="111"
BBB=222
This problem is present on both Qt 4 and Qt 5, on Linux.
Whoa whoa, are you using .ini files or the registry?
With .ini files it's obviously impossible to know what the type was, since it's all a string. You can attempt conversion of the variant to an integer (don't use canConvert!), and assume it's an integer if it converts into one.
With the registry, QSettings will work as you expect it to.
I really don't see what the problem is. Don't use .ini files if you wish to retain type information. You'd face exactly the same problems if you wrote the code by hand in a platform-dependent manner.
You can explicitly write quoted strings into the .ini files, and check for presence of quotes when reading them back. If the quotes are not present, you can try conversion to an integer.
I solved this problem for a component which needs to save and restore variants of arbitrary type, without knowing what its clients expect. The solution was to store the variant's typeName() alongside each value:
void store(QSettings& settings, const QString& key, const QVariant& value)
{
settings.setValue(key+"value", value);
settings.setValue(key+"type", value.typeName());
}
When reading back, we also read the type name, and convert() the variant if it's not already the correct type, before returning it.
QVariant retrieve(const QSettings& settings, const QString& key)
{
auto value = settings.value(key+"value");
const auto typeName = settings.value(key+"type").toString();
const bool wasNull = value.isNull(); // NOTE 1
const auto t = QMetaType::type(typeName.toUtf8()); // NOTE 2
if (value.userType() != t && !value.convert(t) && !wasNull) {
// restore value that was cleared by the failed convert()
value = settings.value(key+"value");
qWarning() << "Failed to convert value" << value << "to" << typeName;
}
return value;
}
Notes
The wasNull variable is in there because of this niggle of convert():
Warning: For historical reasons, converting a null QVariant results in a null value of the desired type (e.g., an empty string for QString) and a result of false.
In this case, we need to ignore the misleading return value, and keep the successfully-converted null variant of the correct type.
It's not clear that UTF-8 is the correct encoding for QMetaType names (perhaps local 8-bit is assumed?); my types are all ASCII, so I just use toLatin1() instead, which might be faster. If it were an issue, I'd use QString::fromLatin1 in the store() method (instead of implicit char* to QString conversion), to ensure a clean round-trip.
If the type name is not found, t will be QMetaType::UnknownType; that's okay, because convert() will then fail, and we'll return the unconverted variant (or a null). It's not great, but it's a corner case that won't happen in normal usage, and my system will recover reasonably quickly.
Turns out the solution was very simple.
When values are written to the INI file, the type is known.
I am appending to the value "\"STRING right before SetValue
When values are read back from the INI file.
I verify that string types have the above postfix.
If they do, I chop the postfix off.
If they don't I assume they are integers instead of strings.
Works like a charm!
Thanks to you all and especially #Kuba Ober for practically handing out the solution.

Convert String to Int with Stringstream

have a little problem here:
int IntegerTransformer::transformFrom(std::string string){
stream->clear();
std::cout<<string<<std::endl;;
(*stream)<<string;
int i;
(*stream)>>i;
std::cout<<i<<std::endl;
return i;
}
I by calling this function with the string "67" (other values dont work too) i get this output:
67
6767
Did you notice there are two std::cout in the function itself?
Beside that also add this:
stream->str(""); //This ensures that the stream is empty before you use it.
(*stream)<<string;
By the way, why don't you use boost::lexical_cast?
int IntegerTransformer::transformFrom(std::string s){
return boost::lexical_cast<int>(s);
}
stream->clear();
This does not "empty out" the stringstream's contents. It resets the error flags that get set when reading from the stream fails (e.g. because the text is not in the right format to read an integer).
The simplest way to deal with this is to just create a new, locally scoped stringstream:
int IntegerTransformer::transformFrom(std::string string){
std::stringstream parser(string);
int i;
parser>>i;
return i;
}
Notice how you also no longer have to mess around with pointers (and, I'm assuming, dynamic allocation), and that you can just use the constructor to set the initial value.
Having streams as data members of a class is a bad idea in general. They really aren't meant for that kind of use.
The next easiest solution is to use the member function that's actually intended for the job, .str(), as shown by Nawaz.
As also mentioned by Nawaz, scrapping the whole thing and just using boost::lexical_cast is probably a better idea anyway. Don't reinvent the wheel.