0

I am trying to modify the code in this answer

https://stackoverflow.com/a/5403170/3657941

so that I have a function that converts a hex string to ASCII values which are stored in an output buffer.

I tried to use snprintf but I am getting a segmentation fault. In GDB I am getting

st=error reading variable: Cannot access memory at address 0x726f6445>
out=error reading variable: Cannot access memory at address 0x726f6441>

Here is my code:

#include <stdio.h>
#include <string.h>

int hex_to_int(char c)
{
    if (c >= 97)
        c = c - 32;
    int first = c / 16 - 3;
    int second = c % 16;
    int result = first * 10 + second;
    if (result > 9) result--;
    return result;
}

int hex_to_ascii(char c, char d){
        int high = hex_to_int(c) * 16;
        int low = hex_to_int(d);
        return high+low;
}

void hs(const char *st, char *out)
{
        //const char* st = "6665646F7261";
        int length = strlen(st);
        int i;
        char buf = 0;
        int offset = 0;

        for(i = 0; i < length; i++){
                if(i % 2 != 0){
                        //printf("%c", hex_to_ascii(buf, st[i]));

                        offset += snprintf(out + offset, 255 - offset, ":%c", hex_to_ascii(buf, st[i]));
                }else{
                        buf = st[i];
                }
        }

}

int main(){

        char str;
        hs("6665646F7261",&str);
        printf("%c\n", str);
}

I expect to send the function hs input "6665646F7261" in hex and get back the ASCII values in "fedora".

Djmc
  • 31
  • 1
  • 4
  • 1
    Your `main` function creates a variable that can only hold a single character and passes its address to a function that tries to store a string there. That won't work. – David Schwartz Jul 13 '19 at 03:11

1 Answers1

-1

This converts the hex pairs into ASCII values and stores them in a buffer:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define TARGET_SIZE(input) \
    ((strlen(input) / 2) + 1)

void convert(char *buffer, char *input) {
    // This version is a little better but we still rely on the caller
    // to give us a large enough buffer
    char storage[3];
    int offset = 0;
    assert(strlen(input) % 2 == 0);
    for (int index = 0; index < strlen(input); index+= 2) {
        storage[0] = input[index];
        storage[1] = input[index + 1];
        storage[2] = 0;
        // Now we handle upper and lower case hex values
        buffer[offset] = strtoul(storage, NULL, 16);
        offset++;
    }
    buffer[offset] = 0;
}

int main(void) {
    char fedora[] = "6665646F7261";
    char buffer[TARGET_SIZE(fedora)];
    convert(buffer, fedora);
    printf("%s\n", buffer);
    return 0;
}

Output

fedora
David Cullen
  • 13,143
  • 4
  • 35
  • 60
  • 1
    Simply providing code with no documentation or explanation, and without explaining what was wrong with the original code, is not a good answer. – Eric Postpischil Jul 13 '19 at 02:12
  • I know. This question should be closed and deleted. However, if the OP just needs to finish his homework, this will get it done. Also, there was so much wrong with the original question, I didn't know where to begin. If you look at the suggested duplicate, the OP code appears to be based on one of the answers. – David Cullen Jul 13 '19 at 02:12
  • Yes this code is based on the duplicate question, but the main difference is I want to call the convert function and get the result back to main instead of printing the result inside the convert function, – Djmc Jul 13 '19 at 02:20
  • Yes, after re-reading your question I realized you wanted to store the value in an intermediate buffer. I modified the answer. I didn't even try to fix your original code because there are so many problems with it. My answer could use improvement as well, but this looks like homework. – David Cullen Jul 13 '19 at 02:26
  • Thank you David it's perfect, I didn't know how to explain my question to make more clear, but no this is not a homework it's just a hobby for home use. – Djmc Jul 13 '19 at 02:37