-3

How would I go about using this function in c++? It should return the ASCII value of a character in a string p with index ip.

#include <cstring>

int ascVal(size_t ip, const char* p)
{
    // Return the ASCII value of the char
    if(!p || ip > strlen(p))
        return -1;
    else
        return p[ip];
}

I would love to learn how to use this function. Thank you.

distinct
  • 7
  • 5
  • Possible duplicate of [Converting a char to ASCII?](http://stackoverflow.com/questions/15505375/converting-a-char-to-ascii) – Cine Oct 03 '16 at 05:24
  • 5
    `int asciivalue = 'a';`? – tkausl Oct 03 '16 at 05:24
  • 4
    The problem with your code is that you allocate a single character, and then use the pointer to that character as an array and try to get index `256` in that array. Which is *way* out of bounds of the single character you allocated. That leads to *undefined behavior*. – Some programmer dude Oct 03 '16 at 05:26
  • The 2nd piece of code seems very confused, sort of like you have put lines together so that they compile, without understanding at all what they do. Also, *"I'm not getting exactly what I expect"*, what do you expect then? – hyde Oct 03 '16 at 05:54

2 Answers2

2

It seems you misunderstood between "character" and "char buffer".

The character buffer is an array of characters. The "size_t" in "ascval" function is nothing but number of characters in your buffer, indexing from zero.

For your understanding I tweaked your code. It works (not optimized)

#include <iostream>
#include <cstring>


int ascVal(size_t ip, const char* p)
{
    // Return the ASCII value of the char
    if(!p || ip > strlen(p))
        return -1;
    else
        return p[ip];
}


int main()
{
    std::cout << ascVal(0,"a") << std::endl;

    char *letter = new char;
    *letter = 'a';
    size_t asciiSize = 0;

    int letterValue = letter[asciiSize];
    std::cout << letterValue << std::endl;



}
Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
0

First a run through of the function because you should understand all of what it is doing in order to appreciate it.

int ascVal(size_t ip, const char* p)
{
    // Return the ASCII value of the char
    if(!p // if p is NULL there is not string ergo nothing vcan be done with it
       || // boolean OR means if either condition is met
       ip > strlen(p)) //the index of the requested character is NOT inside the string  
        return -1; // we can do nothing with input this bad. Return an error
    else
        return p[ip]; // get the ipth character in the string and return the character as 
                      // an integer. This makes the character look like a number. It's 
                      // really been a number the whole time but characters are treated 
                      // and displayed to the user differently than an int
}

And now what OP is doing:

char *letter = new char; // dynamically allocating a block of memory exactly one 
                         // character long
*letter = 'a'; // assigning the letter a to that one character
size_t asciiSize = 256;

int letterValue = letter[asciiSize]; // get the asciiSizeth (256th) character in the block 
                                     // of memory. Unfortunately there is no 256th
                                     // character in that block of memory. This is bad.
cout << letterValue << endl; // print value of 256th character in bloc of one character.

Unlike the above function, OP is not verifying that letter points to anything. This is a moot point since OP just set it a few lines above and knows dang well that letter is a valid pointer. OP is also not ensuing that the array position specified by asciiSize is inside the array.

And this is, I think, where we hit OP's conceptual problem. OP seems to have assumed that because there are 256 values in ASCII, they can just ask for value 256.

Problem 1: Origin 0

Virtually all programming starts counting at 0. If you have 256 possible values, those values are 0 through 255. 256 is too big and something odd will happen. Typically 256 would overflow and become 0, but I wouldn't count on this for all cases.

Problem 2: ASCII is 7 bit

There are only 2 to the power of 7, or 128, ASCII values. Because we usually put the ASCII value in an 8 bit number people have found ways to use the unused 128 values, but this is typically defined by the localization or code page settings of whatever is displaying the value. Don't count on getting what you want without checking first.

Problem 3: Array indexing

letter[asciiSize] is a request for the asciiSize array element after letter. A text book is the better place to look for details on arrays and indexing, but what matters here is you should not ask for memory you don't have and you should not ask for data beyond what is used. This brings us to

Semi problem 4: null termination

*letter = 'a' is simply a pointer to a lone character that happens to be 'a'. This is not a string. To be a string, you need to have some sort of sizing information or a terminator so that you know when to stop reading the string. IN C the terminator is character value 0. It's never used in conversations, so it is the perfect mark to denote the end of a text string. Do not try and use this for binary information. Binary has very different rules. Usually the exact size of binary information is known ahead of time or a sequence that cannot possibly appear in the binary stream is used to mark the end, the terminator. In binary 0 is very common, so you usually have to pick something else.

Here we know letter points to exactly one character because OP put exactly one character there. The pointer has no clue. It's all up to the programmer, and if the programmer allocates one character and then asks for the 100th character, that's their problem.

So to make letter into a string

char *letter = new char[2];
*letter = 'a'; // same as letter[0] = 'a'
letter[1] = '\0'; // same as *(letter + 1) = '\0'

Now we can use strlen to determine the length of the string if we need to.

Putting all that together, if you want a character with a given value, say 42, all you have to do is

char val = 42;

Displaying val will result in '*', the symbol assigned to 42. Why a '*'? No one knows, and Douglas Adams died trying to find out. Douglas! We salute you!

There is no need for array indexing here. All you need is a copy of the ASCII table.

If you really do want the 256th character of a string, you must first make a string large enough and then fill to the 256th character or beyond. Do not assume that because the program didn't crash that there is no 256th character. Test first like the original function did with strlen. Test and pray that whoever provided the string properly terminated it.

user4581301
  • 33,082
  • 7
  • 33
  • 54