0

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?

2
Contributors
7
Replies
9
Views
5 Years
Discussion Span
Last Post by raptr_dflo
0

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

1

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.

0

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.

0

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

0

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.

0

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!

0

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

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.