user1784297
user1784297

Reputation: 105

Suddenly extra index value in my array

My code is:

char randomChar(int randMax) {
    return (65 + rand() % randMax);
}

int main() {

    srand(time(NULL));
    const int SIZE = 4;
    const int LETTERS = 6;
    char code[SIZE];

    for (int i = 0; i < SIZE; i++) {
        code[i] = randomChar(LETTERS);
    }

    cout << code;

    return 0;
}

The problem is that even though I've set the code-array to be of length 4, the randomChar function returns 4 letters + some extra random sign.

Upvotes: 1

Views: 1459

Answers (4)

Jack Aidley
Jack Aidley

Reputation: 20107

In C, strings are zero-terminated this is because the length of a string is not associated with it so there needed to be some way of determining where the string ended. C and C++ do this by placing a zero character at the end of the string. When you do something like char* text = "simples"; the compiler will do this for you but when you're generating your own strings you need to leave space for one more character after the ones you're interested in and set this character to \0.

The reason you're getting spurious characters at the end is that cout is dutifully printing out characters starting with your array until it happens to hit a zero byte which it will interpret as the end of the string.

Thus you want to replace your main() function with this:

int main() {

    srand(time(NULL));
    const int SIZE = 4;
    const int LETTERS = 6;
    char code[SIZE + 1];

    for (int i = 0; i < SIZE; i++) {
        code[i] = randomChar(LETTERS);
    }

    // Need to zero-terminate the string
    code[SIZE] = '\0';
    cout << code;

    return 0;
}

(You could also do code[SIZE] = 0 but I prefer the expressiveness of \0 - both will produce exactly the same effect)

Zero-termination is also one of the principle reasons that string handling in C and C++ is slower than it could be: nearly every string operation needs to scan the string from beginning to end to find the null-terminator.

Upvotes: 0

stefan
stefan

Reputation: 10355

As others pointed out, you're not null-terminating your char array. You can forget about this kind of problem if you use the proper C++ way, i.e. by using std::string which is basically a wrapper class for char arrays. Here's how to implement the same logic in C++:

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

char randomChar(const int randMax) // suggestion, not a necessity: mark randMax as const since you never intend to modify it here.
{
    return ( 65 + std::rand() % randMax );
}

int main()
{
   std::srand(std::time(NULL));
   const int SIZE = 4;
   const int LETTERS = 6;
   std::string code;
   for (int i = 0; i < SIZE; i++)
   {
       code.insert(code.end(), randomChar(LETTERS));
   }
   std::cout << code << std::endl;
   return 0;
}

Upvotes: 0

Hayri Uğur Koltuk
Hayri Uğur Koltuk

Reputation: 3020

Your string is not zero terminated.

You probably have to do this:

char randomChar(int randMax) {
    return (65 + rand() % randMax);
}

int main() {

srand(time(NULL));
const int SIZE = 4;
const int LETTERS = 6;
char code[SIZE + 1];

for (int i = 0; i < SIZE; i++) {
    code[i] = randomChar(LETTERS);
}

code[SIZE] = '\0';
cout << code;


return 0;
}

or, as recommended by commenter @borisbn:

char randomChar(int randMax) {
    return (65 + rand() % randMax);
}

int main() {

srand(time(NULL));
const int SIZE = 4;
const int LETTERS = 6;
char code[SIZE + 1] = {0};

for (int i = 0; i < SIZE; i++) {
    code[i] = randomChar(LETTERS);
}

cout << code;


return 0;
}

However if there's any universe out there in which ('\0' != 0) is true, this latter would fail there.

Upvotes: 0

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70989

You should put a terminating zero character in the array. Otherwise you may get junk printed after the end of the array. Always declare the array with size 1 more than you need and then set the last element to 0.

Try this code:

char randomChar(int randMax) {
    return (65 + rand() % randMax);
}

int main() {

    srand(time(NULL));
    const int SIZE = 4;
    const int LETTERS = 6;
    char code[SIZE + 1];

    for (int i = 0; i < SIZE; i++) {
        code[i] = randomChar(LETTERS);
    }

    code[SIZE] = 0; // or '\0'
    cout << code;

    return 0;
}

Upvotes: 2

Related Questions