0

I'm quite new to C/C++, and I'm putting together a bad knuckle tattoo generator to get used to using strings and seeded random values. The programme should initialise a 9-character string to hold the final knuckle tattoo, generate 2 random sequences of 4 letters using their ASCII values, and then output this to the console. This isn't meant to be particularly good or sexy, I'm just using it to get used to working with arrays and generating random values. This is the code:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

void randomKnuckleTatt(char inputString[]);

void main()
{
    char knuckleTatt[9]; //Will hold final tattoo output

    srand((unsigned int)time(nullptr)); //Seeding rand(void)

    randomKnuckleTatt(knuckleTatt); //Generate a random knuckle tattoo and add to knuckleTatt
    cout << "Your bad knuckle tatt is:\n"
      << knuckleTatt << endl;
}

void randomKnuckleTatt(char inputString[])
{
    int i;
    int randomValue;

    for (i = 0; i <= 3; i++)
    {
        randomValue = int(double(rand()) / RAND_MAX * 25 + 65); //Generate random integer and fit to range
        randomValue = char(randomValue); //Cast as char
        inputString[i] = randomValue; //Assign random ASCII letter to array element
    }

    inputString[4] = char(32);

    for (i = 5; i <= 8; i++)
    {
        randomValue = int(double(rand()) / RAND_MAX * 25 + 65);
        randomValue = char(randomValue);
        inputString[i] = randomValue;
    }
}

So far, randomKnuckleTatt successfully generates a valid knuckle tattoo (ie. two four-letter words separate by a space) from random ASCII values and modifies the knuckleTatt array with these values. However, when knuckleTatt is printed to the console with cout, loads of nonsense ASCII characters are also printed. It always prints the characters contained in knuckleTatt, along with seven of "╠" (ASCII 204 in decimal, if that's not displaying properly for anyone), and then some more junk characters - for example, the most recent output was "UXDP TTKJ╠╠╠╠╠╠╠²┘▬*­¸╗".

I've added a break point in debug on cout << "Your bad knuckle tatt is:\n", and knuckleTatt only contains the 9 ASCII characters generated in randomKnuckleTatt.

Why is this happening, and how do I stop it?

  • 5
    "_Why is this happening_" You didn't null-terminate your string. – Algirdas Preidžius Feb 22 '21 at 12:12
  • 3
    Two four letter words = 8 characters; the space in between makes 9 characters. Then, the **required NULL terminator** makes 10 characters. So, your `knuckleTatt` array isn't large enough. – Adrian Mole Feb 22 '21 at 12:13
  • Nonsense on the end of strings is universally because of a failure to terminate them. Remember that. – WhozCraig Feb 22 '21 at 12:15
  • Note that your `randomKnuckleTat()` function has no way of knowing that the provided pointer allocates enough storage for 10 characters. You'd be better of using e.g. `std::array` or an `std::string`. Some other remarks: you should be using [random number generators provided in ``](https://stackoverflow.com/questions/19665818). [Don't use `using namespace std;`](https://stackoverflow.com/questions/1452721). – AVH Feb 22 '21 at 12:17
  • Also, look at e.g. [`std::generate_n`](https://en.cppreference.com/w/cpp/algorithm/generate_n). Using it would make your code more expressive, i.e. it will be easier to see at a glance what it's doing, instead of having to read all the code. – AVH Feb 22 '21 at 12:19
  • Thanks guys. For now, I've just extended my array to 10 characters and null-terminated it manually, which has fixed the issue, but I'll definitely look into all those suggestions (eg. using ```namespace std;``` and random number generators in a more refined way) – Robert Reid Feb 22 '21 at 12:24

1 Answers1

3

You forgot the room of the null terminator/character (\0) to terminate the character string. So make your array bigger and set the last value to \0.

Use std::string next time.

RvdK
  • 19,580
  • 4
  • 64
  • 107
  • 2
    Note that it is misleading to call the null terminator character "NULL" as that may lead someone to think that the NULL macro has something to do with the terminator character. – eerorika Feb 22 '21 at 12:17
  • Thanks - as mentioned above, I get that I'm not doing this in the most efficient way, so I appreciate any suggestions as to how I can move more towards "good practice" :) – Robert Reid Feb 22 '21 at 12:29