convertHex changes all occurrences of %XX (XX are exactly two hexadecimal digits) to ascii characters. Returns the number of replacements made.

Here are the rules:

Except when defining your character arrays, you must use pointer notation for all c-string manipulation--no []'s allowed. You may use any function from the cctype library, but only strlen(), strstr(), and strncmp() from the cstring library. The C++ string class may not be used.

Here is my stub function:

int convertHex(char *words){
    int changed = 0;

    return changed;
}

I'm thinking the resulting function needs to look like the following function:

//Replace the second string parameter with the third string parameter in the string
int replaceText(char *words, char *replace, char *check){
    char *location;
    int count = 0,
        value = 0,
        shift,
        adjust,
        length = strlen(words),
        difference;
    bool found = false;

    if (strlen(replace) < strlen(check))
        return 0;
    else
        difference = strlen(replace) - strlen(check);

    do{
        location = strstr(words, replace);
        if (location != NULL){
            found = true;
            shift = location - words;
            *(words + shift) = *check;
            for (adjust = shift + 1; adjust < length; adjust++){   
                *(words + adjust) = *(words + adjust + difference);
            }
            count++;
        }
        else
            found = false;
    }while (found);
    return count;
}

Having trouble figuring out what to do once I locate the '%'.

How can I convert the hex characters to a single ascii character and then put that character back into the string?

Recommended Answers

All 7 Replies

Oh... forgot this. Everything is being sent from an object file.

Sample text from object:

"the; big apple mixed from, a %23car one happy boy flew, on some cranberry %27one happy house mixed %29over some; house one big bus skipped .from a cranberry8976 some purple box .%21hopped under a town one purple dog"

Sample output text:

"the; big apple mixed from, a #car one happy boy flew, on some cranberry 'one happy house mixed )over some; house one big bus skipped .from a cranberry8976 some purple box .!hopped under a town one purple dog"

Sample return value:

4

Since you've been told to use pointers rather than array-indexing []-notation, don't think of it so much as "how can i ... put that character back into the string" as "once i've determined the character and replaced the %-sign with it, how do I get rid of the two hex-digits?" Hint: since your replacement will always be shorter than the original text (one character instead of a 3-character %XX hex pattern), if you maintain a read-pointer and a write-pointer, then you can keep copying the character at the read-pointer down to the position of the write-pointer until you hit the next %-sign and then evaluate another encoded character.

The first bit is: do you understand hex notation? If you know, e.g. that %d3 is 211 (in decimal), and why, then it should be reasonably easy to say something like: "if read-ptr points to '%' then val1 is the character after that converted to an integer in the range [0,15], and val2 is second character after that, converted the same way. The byte-value of the two hex-values is (... a number in the range [0,255] ...). And that, converted into a character is '...something...'. And that's what gets written to my write-pointer, and then I move each pointer forward by the correct amount."

What you need to fill in is:
how to convert a hex-digit character to an integer hex-value
how to combine the two hex-values into a single 8-bit integer
how to convert an 8-bit integer into a char type
how far to advance the read-pointer (depending on whether or not you found a %)
how far to advance the write-pointer

Other tidbits:
how do you know when the read-pointer gets to the end of the input text?
given that, what can you do to mark the end of the now-shortened string?
don't forget to keep track of the number of hex-encoded values you've converted to characters.

And you can use the permitted functions to help you find things in the string, rather than stepping through one character at a time, if that's useful to you. I wouldn't bother too much with the code you found, other than to understand what it does, since you're not using a fixed "search" text and fixed "replacement" text.

The second bit of code is one I wrote.

My biggest problem is figuring out what conversions needed to take place since I've never worked with hex characters before.

I'll look into the information you've provided and see if I can dream something up.

Thank you.

Figured this out so far:

hex d3 = (13 * 16) + (3 * 1) = dec 211

Do I have to make my own conversion table for hex values A-F and a-f? I certainly can't just use static cast to change the character to an integer (would be 65-70 and 97-102).

Got it to work. Here's the code I used:

int convertHex(char *words){
    int count,
        first,
        second,
        alphaOffset = 55,
        digitOffset = 48,
        shift,
        length = strlen(words),
        changed = 0,
        converted;
    
    for (count = 0; count < length; count++){
        if (*(words + count)== '%'){
            changed++;
            if (isalpha(*(words + count + 1))){
                *(words + count + 1) = toupper(*(words+ count + 1));
                first = static_cast<int>(*(words + count + 1) - alphaOffset);
            }
            else
                first = static_cast<int>(*(words + count + 1) - digitOffset);
            if (isalpha(*(words + count + 2))){
                *(words + count + 2) = toupper(*(words+ count + 2));
                second = static_cast<int>(*(words + count + 2) - alphaOffset);
            }
            else
                second = static_cast<int>(*(words + count + 2) - digitOffset);
            converted = (first * 16) + second;
            *(words + count) = static_cast<char>(converted);
            for (shift = count + 1; shift < length; shift++){   
                 *(words + shift) = *(words + shift + 2);
            }
        }
    }
    return changed;
}

Is there an easier way? Perhaps. I don't know what it is, but I'll mark the thread solved. Thanks again raptr_dflo.

Since 'A-F' and 'a-f' are separate from '0'-'9' (the characters, not the integers), you would handle them separately, like:

if (*readPtr >= '0' && *readPtr <= '9')
  hexVal = int(*readPtr - '0');  // since '5' is 5 places up from '0', '5' - '0' evaluates to 5
...

Keep in mind that while you can do the same thing with 'a'-'f' and 'A'-'F', that 'a' - 'a' is zero, not 10, so don't forget to add the 10 to get the correct value!

Your way is just fine. Good work! (Sorry, I'm doing too many things at the same time here.) And don't forget to mark your thread as "solved". :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.