CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: conversion

  1. #1
    Join Date
    May 2005
    Posts
    50

    conversion

    hello,

    does someone can tell me how do i convert string with hex values to it's ascii values?

    thanks in advance.

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: conversion

    Code:
    char hex_string[] = "0xAA";
    char ascii;
    
    sscanf(hex_string, "0x%X", &ascii);

  3. #3
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: conversion

    Quote Originally Posted by SunCore
    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"

  4. #4
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: conversion

    Quote Originally Posted by Kheun
    Code:
    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.
    Code:
    char hex_string[] = "0xAA";
    unsigned uascii;
    char ascii;
    
    sscanf(hex_string, "0x%X", &uascii);
    ascii=static_cast<char>(uascii);

  5. #5
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: conversion

    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.

  6. #6
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: conversion

    Quote Originally Posted by Kheun
    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:
    Code:
    // 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++):
    Code:
    push ebp
    mov ebp,esp
    add esp,-7
    mov dword ptr [ebp-4],1
    mov word ptr [ebp-6],2
    mov byte ptr [ebp-7],3
    Now suppose that we write 4 bytes at address ebp-7, it will override the value of b, and even a.

    If we are very lucky, the compiler may not regroup variables, so the asm code could look like that:
    Code:
    push ebp
    mov ebp,esp
    add esp,-12
    mov dword ptr [ebp-4],1
    mov word ptr [ebp-8],2
    mov byte ptr [ebp-12],3
    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++:
    Code:
    #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.
    Last edited by SuperKoko; July 27th, 2005 at 08:49 AM.

  7. #7
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: conversion

    Thank you very much for being thorough and highlighting the potential buffer overflow problem. I would be very lucky that the program runs without crashing. 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.

  8. #8
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: conversion

    Code:
    #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

  9. #9
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: conversion

    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).

  10. #10
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: conversion

    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>).

  11. #11
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: conversion

    Quote Originally Posted by NMTop40
    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.
    Kevin Hall

  12. #12
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: conversion

    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?
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  13. #13
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: conversion

    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.
    Kevin Hall

  14. #14
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: conversion

    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?
    Kevin Hall

  15. #15
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: conversion

    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).

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured