I'm bit hardly to separate the variable String and Integer to passed in "if()" statement.
I have two variable "buffString" and "buffInteger", when i put the buffString in the "if()" statement, I wanna to take String "Data Stop" in the buffString variable, and then set to the RichEdit to showing "Data Stop", but the problem when the buffInteger filled same as buffString its error come in the process. and compilers say "Data Stop" is not valid Integer value
void __fastcall TfrmServer::ComPort1RxChar(TObject *Sender, int Count)
{
String buff;
ComPort1->ReadStr(buff,255);
BUF_RX->Data_suhu = buff; // source
int bufferInteger;
String bufferString;
try{
if(!buff.IsEmpty())
{
bufferInteger = StrToInt(BUF_RX->Data_suhu);
bufferString = BUF_RX->Data_suhu;
if(bufferString == "Data Stop")
{
ad_log_Serial("AT89S52 -> "+BUF_RX->Data_suhu,clRed);
}
else
{
ad_log_Serial("AT89S52 -> "+IntToStr(bufferInteger),clRed);
txtTemp->Text = IntToStr(bufferInteger).c_str();
}
LedRx->States->Items[0]->Value = true;
}
else
{
LedRx->States->Items[0]->Value = false;
}
}__finally
{
delete(BUF_RX);
}
}
what should i do this code?
Move your bufferInteger assignment to the else clause:
else
{
bufferInteger = StrToInt(BUF_RX->Data_suhu);
ad_log_Serial("AT89S52 -> "+IntToStr(bufferInteger),clRed);
txtTemp->Text = IntToStr(bufferInteger).c_str();
}
Since it's not being used outside it, there's no point in having it there. And assuming that any string that's not "Data Stop" is supposed to represent an integer, the code will not fail this way.
Related
I am getting an error that I am having problems fixing as recursion hasn't "sunk in" yet.
It is supposed to go through an array of symbols already placed by the Class OrderManager Object and check if the symbol passed in is already there or not, if it is not there it should allow the trade, otherwise it will block it (multiple orders on the same currency compounds risk)
[Error] '}' - not all control paths return a value.
I believe it is because of the retest portion not having a return value but again I'm still newish to making my own recursive functions. However it may also be because my base and test cases are wrong possibly?
P.S I added (SE) comments in places to clarify language specific things since it is so close to C++.
P.P.S Due to the compiler error, I have no clue if this meets MVRC. Sorry everyone.
bool OrderManager::Check_Risk(const string symbol, uint iter = 0) {
if((iter + 1) != ArraySize(m_symbols) &&
m_trade_restrict != LEVEL_LOW) // Index is one less than Size (SE if
// m_trade_restrict is set to LOW, it
// allows all trades so just break out)
{
if(OrderSelect(OrderManager::Get(m_orders[iter]),
SELECT_BY_TICKET)) // Check the current iterator position
// order (SE OrderSelect() sets an
// external variable in the terminal,
// sort of like an environment var)
{
string t_base = SymbolInfoString(
OrderSymbol(),
SYMBOL_CURRENCY_BASE); // Test base (SE function pulls apart
// the Symbol into two strings
// representing the currency to check
// against)
string t_profit =
SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_PROFIT);
string c_base =
SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); // Current base
// (SE does the same as above but for the passed variable instead):
string c_profit = SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT);
// Uses ENUM_LEVELS from Helpers.mqh (SE ENUM of 5 levels: Strict,
// High, Normal, Low, None in that order):
switch(m_trade_restrict) {
case LEVEL_STRICT: {
if(t_base == c_base || t_profit == c_profit) {
return false; // Restrictions won't allow doubling
// orders on any currency
} else
return Check_Risk(symbol, iter++);
};
case LEVEL_NORMAL: {
if(symbol == OrderSymbol()) {
return false; // Restrictions won't allow doubling
// orders on that curr pair
} else
return Check_Risk(symbol, iter++);
};
default: {
// TODO: Logging Manager
// Hardcoded constant global (SE set to LEVEL_NORMAL):
ENB_Trade_Restrictions(default_level);
return Check_Risk(symbol, iter);
}
}
}
} else {
return true;
}
}
So, I must just have been staring at the code for too long but the problem was the if(OrderSelect(...)) on ln 7 did not have a return case if the order was not properly set in the terminal. I will need to polish this but the following code removes the error.
bool OrderManager::Check_Risk(const string symbol, uint iter=0)
{
if((iter + 1) != ArraySize(m_symbols) && m_trade_restrict != LEVEL_LOW) // Index is one less than Size
{
if(OrderSelect(OrderManager::Get(m_orders[iter]), SELECT_BY_TICKET)) //Check the current iterator position order
{
string t_base = SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_BASE); //Test base
string t_profit = SymbolInfoString(OrderSymbol(), SYMBOL_CURRENCY_PROFIT);
string c_base = SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); //Current base
string c_profit = SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT);
switch(m_trade_restrict) // Uses ENUM_LEVELS from Helpers.mqh
{
case LEVEL_STRICT :
{
if(t_base == c_base || t_profit == c_profit)
{
return false;
}
else return Check_Risk(symbol, ++iter);
};
case LEVEL_NORMAL :
{
if(symbol == OrderSymbol())
{
return false;
}
else return Check_Risk(symbol, ++iter);
};
default: {
// TODO: Logging Messages
ENB_Trade_Restrictions(default_level); //Hardcoded constant global
return Check_Risk(symbol, iter);
}
}
}
else {return Check_Risk(symbol, ++iter);}
}
else {return true;}
}
I have several functions that try and evaluate some data. Each function returns a 1 if it can successfully evaluate the data or 0 if it can not. The functions are called one after the other but execution should stop if one returns a value of 1.
Example functions look like so:
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
... more functions ...
How would be the clearest way to organise this flow? I know I can use if statements as such:
void doSomething(void)
{
if (function1(data))
{
return;
}
if (function2(data))
{
return;
}
... more if's ...
}
But this seems long winded and has a huge number of if's that need typing. Another choice I thought of is to call the next function from the return 0 of the function like so
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function2(data);
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function3(data);
}
... more functions ...
Making calling cleaner because you only need to call function1() to evaluate as far as you need to but seems to make the code harder to maintain. If another check need to be inserted into the middle of the flow, or the order of the calls changes, then all of the functions after the new one will need to be changed to account for it.
Am I missing some smart clear c++ way of achieving this kind of program flow or is one of these methods best. I am leaning towards the if method at the moment but I feel like I am missing something.
void doSomething() {
function1(data) || function2(data) /* || ... more function calls ... */;
}
Logical-or || operator happens to have the properties you need - evaluated left to right and stops as soon as one operand is true.
I think you can make a vector of lambdas where each lambdas contains specific process on how you evaluate your data. Something like this.
std::vector<std::function<bool(std::string&)> listCheckers;
listCheckers.push_back([](std::string& p_data) -> bool { return function1(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function2(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function3(p_data); });
//...and so on...
//-----------------------------
std::string theData = "Hello I'm a Data";
//evaluate all data
bool bSuccess = false;
for(fnChecker : listCheckers){
if(fnChecker(theData)) {
bSuccess = true;
break;
}
}
if(bSuccess ) { cout << "A function has evaluated the data successfully." << endl; }
You can modify the list however you like at runtime by: external objects, config settings from file, etc...
I want to know if a string contains a '1' or '0' so I wrote this code:
if ((input.contains('0'))||(input.contains('1'))) {
ui->answerbox->setText(QString::number(BinToDec(number)));
}
else {
ui->answerbox->setText("Error");
}
If I put in "014", it runs the if block but if I put "4" it runs the else block. What's wrong?
Man this function BinToDec is a total disaster.
bool success;
auto value = input.toInt(&success, 2);
if (success) {
ui->answerbox->setText(QString::number(value));
}
else {
ui->answerbox->setText("Error");
}
I'm having some trouble with the following method and I need some help trying to figure out what I am doing wrong.
I want to return a reference to a Value in a document. I am passing the Document from outside the function so that when I read a json file into it I don't "lose it".
const rapidjson::Value& CTestManager::GetOperations(rapidjson::Document& document)
{
const Value Null(kObjectType);
if (m_Tests.empty())
return Null;
if (m_current > m_Tests.size() - 1)
return Null;
Test& the_test = m_Tests[m_current];
CMyFile fp(the_test.file.c_str()); // non-Windows use "r"
if (!fp.is_open())
return Null;
u32 operations_count = 0;
CFileBuffer json(fp);
FileReadStream is(fp.native_handle(), json, json.size());
if (document.ParseInsitu<kParseCommentsFlag>(json).HasParseError())
{
(...)
}
else
{
if (!document.IsObject())
{
(...)
}
else
{
auto tests = document.FindMember("td_tests");
if (tests != document.MemberEnd())
{
for (SizeType i = 0; i < tests->value.Size(); i++)
{
const Value& test = tests->value[i];
if (test["id"].GetInt() == the_test.id)
{
auto it = test.FindMember("operations");
if (it != test.MemberEnd())
{
//return it->value; is this legitimate?
return test["operations"];
}
return Null;
}
}
}
}
}
return Null;
}
Which I am calling like this:
Document document;
auto operations = TestManager().GetOperations(document);
When I inspect the value of test["operations"] inside the function I can see everything I would expect (debug code removed from the abode code).
When I inspect the returned value outside the function I can see that it's an array (which I expect). the member count int the array is correct as well, but when print it out, I only see garbage instead.
When I "print" the Value to a string inside the methods, I get what I expect (i.e. a well formated json), but when I do it outside all keys show up as "IIIIIIII" and values that aren't strings show up correctly.
rapidjson::StringBuffer strbuf2;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer2(strbuf2);
ops->Accept(writer2);
As this didn't work I decided to change the method to receive a Value as a parameter and do a deep copy into it like this
u32 CTestManager::GetOperationsEx(rapidjson::Document& document, rapidjson::Value& operations)
{
(...)
if (document.ParseInsitu<kParseCommentsFlag>(json).HasParseError())
{
(...)
}
else
{
if (!document.IsObject())
{
(...)
}
else
{
auto tests = document.FindMember("tests");
if (tests != document.MemberEnd())
{
for (SizeType i = 0; i < tests->value.Size(); i++)
{
const Value& test = tests->value[i];
if (test["id"].GetInt() == the_test.id)
{
const Value& opv = test["operations"];
Document::AllocatorType& allocator = document.GetAllocator();
operations.CopyFrom(opv, allocator); //would Swap work?
return operations.Size();
}
}
}
}
}
return 0;
}
Which I'm calling like this:
Document document;
Value operations(kObjectType);
u32 count = TestManager().GetOperationsEx(document, operations);
But... I get same thing!!!!
I know that it's going to be something silly but I can't put my hands on it!
Any ideas?
The problem in this case lies with the use of ParseInSitu. When any of the GetOperations exist the CFileBuffer loses scope and is cleaned up. Because the json is being parsed in-situ when the buffer to the file goes, so goes the data.
I've written the small vala program below, and I don't know how
to manipulate the GLib.Value types, see the code below :
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-level.html
using Gst;
void application_message(Gst.Bus bus, Gst.Message msg) {
var s = msg.get_structure();
if(s == null)
return;
string msgtype = s.get_name();
if(msgtype != "level")
return;
GLib.Value rms = s.get_value("rms");
GLib.Value st = s.get_value("stream-time");
// according to the doc here : http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-level.html
// "rms" is apparently a "GValueArray of gdouble"
// and
// "st" is a GstClockTime, which is a "typedef guint64 GstClockTime"
// I want to create a string representation of the two, ex:
// 72374237490234, [0.234234,0,424234234,0.423423423,0.5345345, ...]
// and I'm clueless as to how to do the conversions or typecasts...
}
void main (string[] args) {
Gst.init (ref args);
try {
var pipeline = Gst.parse_launch(
"pulsesrc device=\"alsa_input.usb-046d_08c9_674634A4-02-U0x46d0x8c9.analog-mono\" ! " +
"level name=wavelevel interval=10000000 ! " +
"wavenc ! filesink location=audioz.wav"
);
var bus = pipeline.get_bus();
bus.add_signal_watch();
bus.message.connect(application_message);
// Set pipeline state to PLAYING
pipeline.set_state (State.PLAYING);
// Creating and starting a GLib main loop
new MainLoop ().run ();
}
catch(Error e) {
print("%s\n", e.message);
}
}
UPDATE :
THe doc for GLib.Value is here : http://www.valadoc.org/#!api=gobject-2.0/GLib.Value
calling strdup_contents() is somewhat satisfactory, but I'd like to manipulate the array in rms,
printl(rms.type().name()) tells me that it's a GstValueList,
so I'd thing that I should cast it to this :
http://www.valadoc.org/#!api=gstreamer-1.0/Gst.ValueList
but vala seems to know nothing of the type Gst.ValueList...
Vala makes working with GLib.Value very easy, it will implicitly convert between GLib.Value and the native types. Throwing GLib.StringBuilder into the mix to build your array, something like this (untested) should do the trick:
GLib.StringBuilder s = new GLib.StringBuilder ();
s.append (((uint64) st).to_string ());
s.append (",[");
{
bool first = true;
foreach ( unowned GLib.Value value in rms.values ) {
if (!first) {
s.append_c (',');
} else {
first = false;
}
s.append (((double) value).to_string ());
}
}
s.append_c (']');