Decimal to hexadecimal conversion using CAPL - capl

Is there any CAPL function for converting decimal value into hexadecimal value? I have already looked in help option of CAPL browser.

Assuming that you want the number to be converted to a string, that you can print out. Either to the write window, into the testreport, etc.
You can use snprintf like this:
snprintf(buffer,elcount(buffer),"%x",integervariable);
where buffer is a char array big enough.
This example is taken from the Vector knowledge base and was among the first result on google.

For hexadecimal equivalent value:
You can make use of _pow function (returns x to the power of y) and while in the following way, which would return you the hexadecimal equivalent value:
double decToHexEquivalent(int n)
{
int counter,remainder,decimal_number,hexadecimal_number = 0;
while(n!=0)
{
remainder = decimal_number % 16;
hexadecimal_number = hexadecimal_number + remainder * _pow(10, counter);
n=n/16;
++counter;
}
return hexadecimal_number;
}
you can call the above function in the following way:
testfunction xyz(int n)
{
write("Hexadecimal:%d", decToHexa(n));
}
Caution: not tested
For hexadecimal value
declare a global variable char buffer[100] in the variable section
variables
{
char buffer[100];
}
and then using snprintf function you can convert an integer variable to a character array, like this:
void dectohexValue(int decimal_number)
{
snprintf(buffer,elcount(buffer),"%02X",decimal_number);
}
then finally you can use the function as follows:
testfunction xyz(int n)
{
dectohexValue(n);
write("Hexadecimal:%s", buffer);
}

Related

How to convert a byte array into a string in CAPL?

I have a byte array and I need to print the elements in a single line.
I tried using 'snprintf()' but it won't take a byte array as its input parameter.
I tried copying the byte array into an integer array and then used the snprintf(), but instead of printing the HEX values, corresponding ASCII values are printed.
You can try this code :
variables
{
int ar[100];
}
on diagResponse TCCM.*
{
char tmp[8]; // Temporary buffer containing single HEX value
char out[301]; // Bigger output string and "local" to function
// Better to place them there (i and response) if they are not global
int i;
byte response[100];
out[0] = 0; // Clear output string
s1 = DiagGetPrimitiveData(this, response, elcount(response));
for (i = 0; i < s1; i++)
{
ar[i] = response[i];
snprintf(tmp, elcount(tmp), "%.2X ", response[i]); // byte to HEX convert
strncat(out, tmp, elcount(out)); // Concatenate HEX value to output string
}
write("HEX Response : %s", out);
}
Olivier

How to detect snprintf failure?

I am using snprintf to format string using user-defined format (also given as string). The code looks like this:
void DataPoint::valueReceived( QVariant value ) {
// Get the formating QVariant, which is only considered valid if it's string
QVariant format = this->property("format");
if( format.isValid() && format.type()==QMetaType::QString && !format.isNull() ) {
// Convert QString to std string
const std::string formatStr = format.toString().toStdString();
LOGMTRTTIINFO(pointName<<"="<<value.toString().toUtf8().constData()<<"=>"<<formatStr<<"["<<formatStr.length()<<'\n');
// The attempt to catch exceptions caused by invalid formating string
try {
if( value.type() == QMetaType::QString ) {
// Treat value as string (values are allways ASCII)
const std::string array = value.toString().toStdString();
const char* data = (char*)array.c_str();
// Assume no more than 10 characters are added during formating.
char* result = (char*)calloc(array.length()+10, sizeof(char));
snprintf(result, array.length()+10, formatStr.c_str(), data);
value = result;
}
// If not string, then it's a number.
else {
double data = value.toDouble();
char* result = (char*)calloc(30, sizeof(char));
// Even 15 characters is already longer than largest number you can make any sense of
snprintf(result, 30, formatStr.c_str(), data);
LOGMTRTTIINFO(pointName<<"="<<data<<"=>"<<formatStr<<"["<<formatStr.length()<<"]=>"<<result<<'\n');
value = result;
}
} catch(...) {
LOGMTRTTIERR("Format error in "<<pointName<<'\n');
}
}
ui->value->setText(value.toString());
}
As you can see I assumed there will be some exception. But there's not, invalid formatting string results in gibberish. This is what I get if I try to format double using %s:
So is there a way to detect that invalid formatting option was selected, such as formatting number as string or vice-versa? And what if totally invalid formatting string is given?
You ask if it's possible to detect format/argument mismatch at run-time, right? Then the short and only answer is no.
To expand on that "no" it's because Variable-argument functions (functions using the ellipsis ...) have no kind of type-safety. The compiler will convert some types of arguments to others (e.g. char or short will be converted to int, float will be converted to double), and if you use a literal string for the format some compilers will be able to parse the string and check the arguments you pass.
However since you pass a variable string, that can change at run-time, the compiler have no possibility for any kind of compile-time checking, and the function must trust that the format string passed is using the correct formatting for the arguments passed. If it's not then you have undefined behavior.
It should be noted that snprintf might not actually fail when being passed mismatching format specifier and argument value.
For example if using the %d format to print an int value, but then passing a double value, the snprintf would happily extract sizeof(int) bytes from the double value, and interpret it as an int value. The value printed will be quite unexpected, but there won't be a "failure" as such. Only undefined behavior (as mentioned above).
Thus it's not really possible to detect such errors or problems at all. At least not through the code. This is something that needs proper testing and code-review to catch.
What happens when snprintf fails? When snprintf fails, POSIX requires that errno is set:
If an output error was encountered, these functions shall return a negative value and set errno to indicate the error.
Also you can find some relevant information regarding how to handle snprintf failures Here.

Extract trailing int from string containing other characters

I have a problem in regards of extracting signed int from string in c++.
Assuming that i have a string of images1234, how can i extract the 1234 from the string without knowing the position of the last non numeric character in C++.
FYI, i have try stringstream as well as lexical_cast as suggested by others through the post but stringstream returns 0 while lexical_cast stopped working.
int main()
{
string virtuallive("Images1234");
//stringstream output(virtuallive.c_str());
//int i = stoi(virtuallive);
//stringstream output(virtuallive);
int i;
i = boost::lexical_cast<int>(virtuallive.c_str());
//output >> i;
cout << i << endl;
return 0;
}
How can i extract the 1234 from the string without knowing the position of the last non numeric character in C++?
You can't. But the position is not hard to find:
auto last_non_numeric = input.find_last_not_of("1234567890");
char* endp = &input[0];
if (last_non_numeric != std::string::npos)
endp += last_non_numeric + 1;
if (*endp) { /* FAILURE, no number on the end */ }
auto i = strtol(endp, &endp, 10);
if (*endp) {/* weird FAILURE, maybe the number was really HUGE and couldn't convert */}
Another possibility would be to put the string into a stringstream, then read the number from the stream (after imbuing the stream with a locale that classifies everything except digits as white space).
// First the desired facet:
struct digits_only: std::ctype<char> {
digits_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
// everything is white-space:
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
// except digits, which are digits
std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
// and '.', which we'll call punctuation:
rc['.'] = std::ctype_base::punct;
return &rc[0];
}
};
Then the code to read the data:
std::istringstream virtuallive("Images1234");
virtuallive.imbue(locale(locale(), new digits_only);
int number;
// Since we classify the letters as white space, the stream will ignore them.
// We can just read the number as if nothing else were there:
virtuallive >> number;
This technique is useful primarily when the stream contains a substantial amount of data, and you want all the data in that stream to be interpreted in the same way (e.g., only read numbers, regardless of what else it might contain).

What's in xcode console with scanf ,when want a number but input a char?

xcode 5.0
when I run following code:
void guessNum(){
int answer = 0;
int guess = 0;
int turn = 0;
answer = arc4random() % 100 + 1;
while (guess != answer) {
turn++;
NSLog(#"Guess #%i: Enter a number between 1 and 100", turn);
scanf("%i", &guess);
if (guess > answer) {
NSLog(#"Lower!");
}
else if (guess < answer) {
NSLog(#"Higher!");
}
else {
NSLog(#"Correct! The answer was %i", answer);
}
} // end of while loop
NSLog(#"It took you %i tries", turn);
}
when I type a character, just like a in xcode debug console, program run automatic and print:
...
2013-11-18 10:47:39.719 donglix[15115:303] Higher!
2013-11-18 10:47:39.719 donglix[15115:303] Guess #1932: Enter a number between 1 and 100
2013-11-18 10:47:39.719 donglix[15115:303] Higher!
2013-11-18 10:47:39.720 donglix[15115:303] Guess #1933: Enter a number between 1 and 100
...
what's the problem?
"scanf()" reads the input you've typed in and, because of your "%i" (integer) format string, is expecting to take that input and drop it into a number.
If you used "%s" as your format string, then you would take the input as a C-style character array (and have to convert those characters if you wanted to get the integer value out of that).
For example, you can replace this line:
scanf("%i", &guess);
with something like this:
char stringToConvert[256]; // if you type more than 256 characters, you'll crash
sscanf("%s",&stringToConvert);
guess = atoi(stringToConvert); // this function converts the string into an integer
If you type in the character "a", scanf converts that to 97 in the ascii table.

VBS running code from string

I have one string storing hexadecimal data (\xEA\x...). Is it anyway to run that code using vbs? Maybe doing some kind of casting to function pointer or similar.
The C version of what I'm trying to do would be:
unsigned char opcode[] = "\xc0\x...."
main()
{
int (*run)() = (int(*)())opcode;
run();
}
Thank you so much.
You can use function pointers (or function references) with the GetRef function:
dim fp : set fp = GetRef("ShowMessage")
call fp("Woosh")
function ShowMessage(msg)
msgbox msg
end function
To make this work for any string with normally illegal characters for function naming (like the backslash in hexadecimal data) you can use brackets in you function declaration:
dim fp : set fp = GetRef("99 problems")
call fp()
' note: functions normally cannot start with a digit or contain spaces
function [99 problems]()
msgbox "but this aint one"
end function
The only character you cannot use is a closing bracket: ]

Resources