Random numbers on unsigned chars keeps being '?'

Go To StackoverFlow.com

1

I've previously asked a question related to generating a random unsigned char and pretty good suggestions came along the way however due to simplicity I've applied ; srand((unsigned)time(NULL)); rand()%256;

I call the srand one time at the beginning of the program, however I keep getting '?' for a random char. Not all the time but most of the time and that causes me to lose my focus.

2012-04-04 17:05
by Ali
Are you checking the numeric value, and seeing that it's actually ? (ASCII value 63)? Or are you just printing the character? If so, then it's possible that any non-ASCII values (such as the range 128-255) are printed as ?. Try converting to int before printing it - Mike Seymour 2012-04-04 17:09
Please describe what you observe that makes you think that you are getting '?' for random char. Better yet, please provide a short, complete test program. See http://sscce.org/ - Robᵩ 2012-04-04 17:13


9

Most probably you keep getting random chars that your terminal does not need how to print and outputs ?. Try converting them to int before printing:

std::cout << (int)my_random_char;
2012-04-04 17:08
by David Rodríguez - dribeas
Thanks a lot, that solved my problem. I'm currently working on Mac would the characters be shown on a Ubuntu Terminal - Ali 2012-04-04 17:12
@rolandbishop: Some might some might not. It depends on the configuration of the terminal, the character set... If you are generating random numbers you should print numbers not characters, and that is what the conversion to int comes into play. If what you want are real characters, then consider using only the printable subset - David Rodríguez - dribeas 2012-04-04 17:25


5

You're not getting '?' as a character, it is being printed that way because the character selected isn't printable. Print it as an integer and you will see that the value is random as you would expect.

2012-04-04 17:09
by Kyle Jones


3

Depending on your platform the values [128 255] may not be valid characters on their own. If you want a random, printable ascii character then you need to generate chars in the range [32 127).

Here's code modified from my answer to your other question, to select only printable ascii characters.

int main() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    auto rand = std::bind(std::uniform_int_distribution<char>(' ','~'),
                          std::mt19937(seed));

    std::generate_n(std::ostream_iterator<char>(std::cout," "), 25, rand);
}
2012-04-04 17:09
by bames53
@rolandbishop: Note that C++ doesn't guarantee that any range of character values is printable, but 32-127 tends to work on almost everything - Mooing Duck 2012-04-04 17:29
Yes, it's possible that an implementation might not be ascii compatible. Though these days everything is, except for exotic systems - bames53 2012-04-04 18:02


1

A few things to consider:

  1. don't call srand() before each invocation of rand(). Call it once when your program starts (if you really want to).
  2. Try outputting the unsigned chars as integers to see what happens.
2012-04-04 17:09
by Axel
already said that I was calling it once.. - Ali 2012-04-04 17:11
Oh yes... go for the integers then as others have pointed out as well. Seems most of the time you get values outside of ascii range that are represented as '?' on the terminal - Axel 2012-04-04 17:12
PS: And you added that in your edit right? I could swear I hadn't seen it before - Axel 2012-04-04 17:13
I've written 'stand' instead of 'stand'. Edited tha - Ali 2012-04-04 17:14


1

Unsigned chars are not characters; they're bytes. You're getting random bytes between 0 and 255 (inclusive), and some of these (or most, depending on encoding) are not valid characters.

If you want a random character between a and z, for example, use something like

unsigned char c = 'a' + rand() % 26;

(rand() % 26 is not the recommended way of doing this, but it's good enough for most applications. See the manpage.)

2012-04-04 17:11
by Thomas
Ads