Случайные числа на беззнаковых символах продолжают быть '?'

Ранее я задавал вопрос, связанный с генерацией случайного символа без знака, и, тем не менее, из-за простоты я применил довольно хорошие предложения; srand((unsigned)time(NULL)); rand()%256;

Я звоню в srand один раз в начале программы, но продолжаю получать "?" для случайного символа. Не все время, но большую часть времени, и это заставляет меня терять концентрацию.


person Ali    schedule 04.04.2012    source источник
comment
Вы проверяете числовое значение и видите, что оно на самом деле ? (значение ASCII 63)? Или вы просто печатаете символ? Если это так, то возможно, что любые значения, отличные от ASCII (например, диапазон 128–255), будут напечатаны как ?. Перед печатью попробуйте преобразовать его в int.   -  person Mike Seymour    schedule 04.04.2012
comment
Пожалуйста, опишите, что вы наблюдаете, что заставляет вас думать, что вы получаете '?' для случайного символа. А еще лучше, представьте короткую, полную программу тестирования. См. sscce.org.   -  person Robᵩ    schedule 04.04.2012


Ответы (5)


Скорее всего, вы продолжаете получать случайные символы, которые вашему терминалу не нужны для печати и вывода ?. Перед печатью попробуйте преобразовать их в int:

std::cout << (int)my_random_char;
person David Rodríguez - dribeas    schedule 04.04.2012
comment
Большое спасибо, что решила мою проблему. Я сейчас работаю на Mac, будут ли символы отображаться в терминале Ubuntu? - person Ali; 04.04.2012
comment
@rolandbishop: Кто-то может, кто-то нет. Это зависит от конфигурации терминала, набора символов ... Если вы генерируете случайные числа, вы должны печатать числа, а не символы, и именно это преобразование в int вступает в игру. Если вам нужны настоящие символы, рассмотрите возможность использования только подмножества для печати. - person David Rodríguez - dribeas; 04.04.2012

Вы не получаете "?" как символ, он печатается таким образом, потому что выбранный символ не печатается. Выведите его как целое число, и вы увидите, что значение случайно, как и следовало ожидать.

person Kyle Jones    schedule 04.04.2012

В зависимости от вашей платформы значения [128 255] могут не быть допустимыми символами сами по себе. Если вам нужен случайный печатный символ ascii, вам нужно сгенерировать символы в диапазоне [32 127).

Вот код, измененный из моего ответа на ваш другой вопрос, чтобы выбрать только печатаемые символы ascii.

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);
}
person bames53    schedule 04.04.2012
comment
@rolandbishop: обратите внимание, что C ++ не гарантирует, что какой-либо диапазон значений символов можно распечатать, но 32–127 работает практически со всем. - person Mooing Duck; 04.04.2012
comment
Да, возможно, что реализация может быть несовместимой с ascii. Хотя сейчас все есть, кроме экзотических систем. - person bames53; 04.04.2012

Несколько вещей, которые следует учитывать:

  1. не вызывайте srand() перед каждым вызовом rand(). Вызовите его один раз при запуске вашей программы (если вы действительно этого хотите).
  2. Попробуйте вывести беззнаковые символы как целые числа, чтобы увидеть, что произойдет.
person Axel    schedule 04.04.2012
comment
О да ... тогда переходите к целым числам, как указывали другие. Кажется, большую часть времени вы получаете значения за пределами диапазона ascii, которые представлены как '?' на терминале. - person Axel; 04.04.2012
comment
PS: И вы добавили это в свою правку, верно? Могу поклясться, что раньше не видел. - person Axel; 04.04.2012
comment
Я написал «стоять» вместо «стоять». Отредактировал это - person Ali; 04.04.2012

Беззнаковые символы не являются символами; они байты. Вы получаете случайные байты от 0 до 255 (включительно), и некоторые из них (или большинство, в зависимости от кодировки) не являются допустимыми символами.

Например, если вам нужен случайный символ между a и z, используйте что-то вроде

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

(rand() % 26 - это не рекомендуемый способ сделать это, но он достаточно хорош для большинства приложений. См. Справочную страницу.)

person Thomas    schedule 04.04.2012