Click to See Complete Forum and Search --> : conversion
SunCore
July 26th, 2005, 07:04 AM
hello,
does someone can tell me how do i convert string with hex values to it's ascii values?
thanks in advance.
Kheun
July 26th, 2005, 07:38 AM
char hex_string[] = "0xAA";
char ascii;
sscanf(hex_string, "0x%X", &ascii);
SuperKoko
July 26th, 2005, 07:47 AM
does someone can tell me how do i convert string with hex values to it's ascii values?
Can you be more specific?
Do you mean converting "413F2042" to "A? B", or converting "hello \x2F\x41" to "hello ?A"
Or converting "0xFF" to "255", letting "255" be converted (just copied) to "255"
Or do you mean converting "FF" to "255"
SuperKoko
July 26th, 2005, 07:51 AM
char hex_string[] = "0xAA";
char ascii;
sscanf(hex_string, "0x%X", &ascii);
Even if this code works with little-endian machines with 4 bytes stack alignment, it is preferable (and ISO compliant) to use unsigned int pointers.
Well, my understanding is that the OP is asking for a way to convert heximal string representation into an ascii character. Since it is only a character, I don't see any reason why endianness is only to affect it. Anyway, the C standard library function like printf() and scanf() interpret the string in human readable form. So we don't ready have to worry about it.
I don't understand why it is preferrable to use unsigned char for this case. Since the resulting value will be the same, why you need to add an extra step in the conversion? Please explain.
SuperKoko
July 27th, 2005, 08:41 AM
I don't understand why it is preferrable to use unsigned char for this case. Since the resulting value will be the same, why you need to add an extra step in the conversion? Please explain.
sscanf don't do RTTI, it just interprets the pointer passed to the function, as a pointer to an unsigned long value, so with one or more mov assembly instructions, it modifies the four bytes pointed by the pointer passed as its argument.
But if you take address of a char, we can just assume that there is only one valid byte of pointed data, no more.
So, sscanf may theorically crash if we pass the address of a char.
In fact, with x86 processors, the data on the stack is aligned on 4 bytes boundaries (some compilers may regroup some variables).
For example, consider this stack frame:
// local variable declarations
int a=1;
short b=2;
char c=3;
// we use addresses of these variables, so they are put on the stack.
The assembly code frame may be (i tried with BC++):
In that case, it will work correctly, but i suppose that only very old compilers may produce this code.
As an example, i tried to compile this code with BC++:
#include <cstdio>
void f(void *)
{}
int main()
{
int i=0;
f(&i); // make sure that i is not optimized.
char c;
std::sscanf("FFFFFFFF","%X",&c); // very bad!
std::printf("%08X",i);
return 0;
}
The output is "00FFFFFF"
I also compiled it with GCC, and the output is identical : "00FFFFFF"
I tried with Watcom C++, and the output is finally "0" with this compiler.
Kheun
July 27th, 2005, 08:00 PM
Thank you very much for being thorough and highlighting the potential buffer overflow problem. :thumb: I would be very lucky that the program runs without crashing. :D Anyway, rechecking the MSDN for format specification field, the appropriate variable type should be unsigned interger instead.
As for RTTI, it is normally turned off by default. Even if we are writing C++ code using STL, it is not being used at all. It is only used when we write some code that does a downcasting from base pointer to derived pointer. It is also being used for retrieving the class type. Since it is vendor specific and varies from compiler to compiler, it is normally not preferrable. In fact, IMO, using RTTI is against the very essence of OOP. This is because using polymorphism helps us to avoid writing code with switch-case statement that determine the appropriate action based on class type while when RTTI and dynamic_cast is used, you have to do that.
NMTop40
July 28th, 2005, 04:13 AM
#include <sstream>
#include <iomanip>
int main()
{
std::string hexstr("239a3c");
std::istringstream iss(hexstr);
int value;
iss >> std::setbase(16) >> value;
std::cout << "value is " << value << std::endl;
}
value is 2333244
SuperKoko
July 28th, 2005, 04:22 AM
When i said that sscanf don't do RTTI, i was not thinking of the RTTI of OOP, but the run time type identification in general, which is physically impossible with the _cdecl calling convention (and others calling conventions), because a raw pointer to raw data is passed on the stack.
In C++ RTTI can only exists for classes designed to be RTTI classes (generally, they have a VTable pointer). Moreover, you can do RTTI with a pointer to a base RTTI class, but even if objects support RTTI, you cannot do RTTI with a void* pointer to such objects.
note that, i agree that RTTI is evil (especially with switch statements), except when used smartly.
dynamic_cast has a main application : allowing horizontal cast in a class hierarchy with multiple inheritance, allowing to add the notion of interfaces in C++.
dynamic_cast can also be used in debug versions of a project to check a conversion from parent-class pointer to child-class pointer which can be done with a static_cast. This usage is useless for release versions (except if you suspect that your project is highly buggy, and you want detailed report bugs from the users).
NMTop40
July 28th, 2005, 05:31 AM
RTTI is generally evil, although exception handling uses it.
streaming uses compile-time operator overloading though, not RTTI.
scanf() and its family of functions do no type-safety checking at all, you just pass them an address and they write into it.
dynamic_cast should be used for one purpose only: loading symbols from a dynamic library, then checking they are of the type you want. In order to do that you have to know that the symbols are derived from a known base class.
For example, maybe you have a generic type called "factory". Now if you load a symbol with dlsym / GetProcAddress and cast it to "factory *", you might want to then check it is of the factory type to your object. (Note that can be a problem if you use templates, as Factory<Derived> is not derived from Factory<Base>).
KevinHall
July 28th, 2005, 09:54 AM
RTTI is generally evil, although exception handling uses it.
Please explain further. I've seen Andrei Alexandrescu do some pretty amazing things with RTTI that don't have to do with exception handling. I'm curious why you say it is generally evil.
Graham
July 28th, 2005, 11:06 AM
I've always thought that switching on RTTI is an admission of defeat. Wanting to know the run-time type of something implies that you have a polymorphic object, but that the interface you have (the base class) is not specified well enough to let you do the job. That, or the function takes an argument that's too high up the hierarchy and should really take a more specialised type. Once you start downcasting, then you're exposing yourself to maintenance problems, since you're coupling your code to specific derivatives and thus lessening your ability to modify those derivatives or to add new ones.
I don't recall Alexandrescu doing that much with RTTI - do you have some specific examples?
KevinHall
July 28th, 2005, 11:19 AM
In his "Modern C++ Design" book, he used RTTI to do some multiple type-switch capabilities. I believe he also did some factory or visitor pattern using RTTI, but I can't recall off the top of my head.
I admitt that RTTI is not perfect, and should be used carefully, but they sometimes do solve problems not easily solvable in other ways. I've just have never heard anyone come out and declare RTTI evil before.
KevinHall
July 28th, 2005, 11:25 AM
So RTTI in many situations may be an admission of defeat. But is that evil?
Macro functions have been declared evil since template functions (a) provide true functional behavior and (b) provide type safety.
Exception specifications are evil because it easily leads to situations where teminate() can be called unexpectedly. It also prevents optimizations (and frequently downgrades performance). Many believe that if the consequences of exception specifications were known in 1998, the standards comittee would have omitted them from the standard.
So, what is it about RTTI that is evil? If C++ were designed again, why would RTTI be omitted?
NMTop40
July 28th, 2005, 11:32 AM
I virtually never use throw() specifications apart from the empty one (guaranteeing no throw) and then I only use that sparingly (it's more of a comment).
KevinHall
July 28th, 2005, 12:33 PM
Here's an interesting quote from "C++ Coding Standards" (Sutter / Alexandrescu) on exception specifications (taken from Item 75: Avoid exception specifications):
The main problems with exception specifications are that they're only "sort of" part of the type system, they don't do what most people think, and you almost always don't want what they actually do.
...
They cause the compiler to inject additional run-time overhead in the form of implicit try/catch blocks around the function body to enforce via run-time checking that the function does in fact emit only listed exceptions (possibly none), unless the compiler can statically prove that the exception specification can never be violated in which case it is free to optimize the checking away. And exception specifications can both enable and prevent further compiler optimizations (beside the inherent overhead already described); for example, some compilers refuse to inline functions that have exception specifications.
Worst of all, however, is that exception specifications are a blunt instrument: When violated, by default they immediately terminate your program. You can register an unexpected_handler, but it's highly unlikely to help you much because you get exactly one global handler and the only way the only way the handler could avoid immediately calling terminate would be to rethrow an exeption that is permissible, but [it's hard to see how the handler could] know what exeptions might be legal without trivializing exception specifications altogether.
...
[BoostLRG]'s experience is that a throws-nothing exceptio specification (i.e., throw()) on a non-inline function "may have some benefit with some compilers." Not a stunning endorsement from one of the most highly regarded and expertly designed C++ library projects in the world.
SuperKoko
July 28th, 2005, 01:23 PM
RTTI does not always mean downcasting, nor ugly switches.
RTTI can be used to do horizontal casting (and should only be used for that).
RTTI can be used to implement the equivalent of Java interfaces.
It is not ugly at all (even if it is not common to use interfaces in C++), it is even better for code reuse and beautiful class design than classical C++ design.
In fact i don't use interfaces in my project, and i generally deactivate RTTI with a compiler option.
It is just a non commonly used language feature.
so, dynamic_cast is not always evil.
But typeid is always evil except to get debugging informations. It should never be used in a release version of a project.
Graham
July 28th, 2005, 01:40 PM
So RTTI in many situations may be an admission of defeat. But is that evil?
I'm not the one who said it was...
KevinHall
July 28th, 2005, 01:49 PM
I'm not the one who said it was...
I know you didn't. I just wanted to prevent what you said being used as an argument for the person that did make the statement.
While waiting for an explanation of why RTTI is evil, I scanned "C++ Coding Standards" and there is no item in there mentioning avoiding RTTI or dynamic_cast. However, Item 93 actually encourages the use of dynamic_cast as a safe alternative to static_cast. (It also suggests refactoring and redesign as options too as designing away downcasting is prefferable. But not everything falls under that category.)
HighCommander4
July 28th, 2005, 03:34 PM
Here's an interesting quote from "C++ Coding Standards" (Sutter / Alexandrescu) on exception specifications (taken from Item 75: Avoid exception specifications):
Why does violating an exception specification cause a call to terminate() at runtime? In Java, the violation of an exception specification causes a compile error which, in my opinion, is a good thing is it not?
KevinHall
July 28th, 2005, 03:50 PM
In C++, you can't catch every exception specification violation at compile-time. For example, a DLL might throw something you didn't expect it to.
- Kevin
SuperKoko
July 28th, 2005, 03:52 PM
Why does violating an exception specification cause a call to terminate() at runtime? In Java, the violation of an exception specification causes a compile error which, in my opinion, is a good thing is it not?
When an incorrect exception is thrown at runtime in a function (or function called directly or indirectly by the function) which has an exception specification, and this exception is not caught inside the function (nor inside the function called by the function), it calls the std::unexpected function which terminates the program by default (this behavior can be changed, but generally we can't do much more than terminating the program).
KevinHall
July 28th, 2005, 03:53 PM
It's also because in C++, exception specifications are only (in the words of Sutter/Alexandrescu) "sort of" part of the type-system. Exception specifications are not strongly enforced everywhere. If exception specifications were strongly enforced, they would be safer than they currently are (but they may still have other problems).
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.