4

I need to program a lotto generator for my education that will randomly roll numbers and check for duplicate entries and replace them otherwise. When I start the program there are no error messages and the program runs but I only see strange characters instead of numbers. A picture of the problem

What is wrong with my code?

#include <iostream>
#include <array>
#include <time.h>

std::array<unsigned char, 6> lottoZahlen = {0, 0, 0, 0, 0, 0};

void arrayFuellen();
unsigned char checkDuplikate(unsigned char);
void arraySortieren();

int main()
{
    arrayFuellen();
    arraySortieren();

    std::cout << "\n---- Ihre Glueckszahlen lauten: ----" << std::endl;

    for (unsigned char lottoGlueck : lottoZahlen)
    {
        std::cout << lottoGlueck << std::endl;
    }

    std::cout << "---- Glueckszahlen Ende ----" << std::endl;
}


void arrayFuellen()
{
    srand(time(NULL));

    unsigned char wuerfelZahl = 0;
    unsigned char wuerfelZahlChecked = 0;

    for (unsigned char i = 0; i < sizeof(lottoZahlen); i++)
    {
        wuerfelZahl = rand() % 45 + 1;
        wuerfelZahlChecked = checkDuplikate(wuerfelZahl);
        lottoZahlen[i] = wuerfelZahlChecked;
    }
}

unsigned char checkDuplikate(unsigned char checkZahl)
{
    srand(time(NULL));
    bool dublette = false;

    do
    {
        dublette = false;

        for (unsigned char j = 0; j < sizeof(lottoZahlen); j++)
        {
            if (checkZahl == lottoZahlen[j])
            {
                checkZahl = rand() % 45 + 1;
                dublette = true;
            }
        }
    } while (dublette);

    return checkZahl;
}

void arraySortieren()
{
    unsigned char merker = 0;
    bool vertauscht = false;

    do
    {
        vertauscht = false;

        for (unsigned char i = 1; i < sizeof(lottoZahlen); i++)
        {
            if (lottoZahlen[i - 1] > lottoZahlen[i])
            {
                merker = lottoZahlen[i];
                lottoZahlen[i] = lottoZahlen[i - 1];
                lottoZahlen[i - 1] = merker;
                vertauscht = true;
            }
        }
    } while (vertauscht);
}
preAlpha
  • 43
  • 5
  • Good job writing a complete question. One suggestion, in the future include the picture instead of a link to the picture. That link may not work later and the "strange characters" will be lost. – Matt Jun 15 '20 at 13:48
  • 2
    First of all, instead of sizeof(lottoZahlen) use lottoZahlen.size(). I think it may be the source of the problem. – Tihran Jun 15 '20 at 13:49
  • Which OS? With windows you have to do a bit more work to print non-ascii. – Mgetz Jun 15 '20 at 13:53
  • 1
    [You're not seeding correctly](https://stackoverflow.com/q/7343833/10077), and you'd be better off [using the C++ random library](https://stackoverflow.com/q/19665818/10077). – Fred Larson Jun 15 '20 at 13:54
  • @Mgetz Yes I'm using Windows. – preAlpha Jun 15 '20 at 13:57
  • Does this answer your question? [Output unicode strings in Windows console app](https://stackoverflow.com/questions/2492077/output-unicode-strings-in-windows-console-app) – Mgetz Jun 15 '20 at 14:08
  • @Mgetz: I don't think this question has anything to do with Unicode strings. It's just inadvertently printing `unsigned char` as characters when it means to print them as integer values. – Fred Larson Jun 15 '20 at 14:17

4 Answers4

4

"char" is a type that is used to store characters, and the output stream will interpret it as such in your for-loop. So if you have value 65, it will actually be displayed as a capital A (which has ASCII value 65). To display numbers, you should use a type that the output stream recognizes as a number, such as "int".

H. Guijt
  • 3,325
  • 11
  • 16
  • But isn't it so that char uses less memory than int? That's why I thought I would use char because to my knowledge there is no byte (like in Java) data type? – preAlpha Jun 15 '20 at 14:15
  • 1
    @preAlpha Indeed, but at a semantic level, `char` and `int` are not printed the same way since `char` is supposed to represent characters. **If you want to print** the underlying numeric value of a `char`, you will need to cast it: `std::cout << static_cast(my_char) << '\n';` By the way, there is a [`std::byte`](https://en.cppreference.com/w/cpp/types/byte) type, but it might not be what you seek (this is not an arithmetic type). – Fareanor Jun 15 '20 at 14:20
  • @Fareanor Okay, yeah, that makes sense. Thanks for the tip. So should I use the datatype int even for such small numbers? Or is it better to use char and then convert it afterwards? – preAlpha Jun 15 '20 at 14:45
  • 1
    @preAlpha To be honest, unless you have memory limitations (embedded systems), you can use integer types instead. But there is absolutely no problem to use `char` like you do. Keep in mind that if you use arithmetic operations, your `char` variables will be promoted into `int` due to _integral promotion_. You can find more details about how integral promotion works [here](https://en.cppreference.com/w/cpp/language/implicit_conversion) – Fareanor Jun 15 '20 at 17:06
1

There are several ways of doing what you want, printing char as integer/decimal value:

  1. using casging int():

    std::cout << int(lottoGlueck) << "\n";
    
  2. using good old (C style) printf(), some would say do not use this, but there are advantages and disadvantages to using printf().

    printf("%d\n", lottoGlueck);
    
  3. As suggested, you can use std::to_string(), I personally do not recommend this for printing a single character, simply because it converts a character to a string to print out an integer.

In production code I use number 1, in debugging I use 2. There are disadvantages/advantages to using both, but you can read this to better understand those.

When it comes to pinging strings as decimal values, you have std::to_string() and also std::cout << std::dec << string << "\n".

  • Thank you for this detailed and enlightening contribution. It was the best way to solve my problem. Thanks a lot! – preAlpha Jun 15 '20 at 14:50
0

you are printing non printable characters: https://upload.wikimedia.org/wikipedia/commons/d/dd/ASCII-Table.svg the ones between [] are not printable characters.

if you write: int i = 5 and then std::cout << i

it will print the corresponding character, with value 5. But the value 5 is not the character '5', so if you expect it to be a printable number, you need to convert it: std::cout << std::to_string(i)

(not sure if this was your intention though :) )

crsn
  • 609
  • 4
  • 11
  • 1
    I guess this is a typo or a careless mistake, but your example is wrong. You should declare `i` as a `char` and not as an `int` in order to observe the described behaviour ;) – Fareanor Jun 15 '20 at 13:57
  • 1
    the std::to_string() has solved my problem. Thanks for that! – preAlpha Jun 15 '20 at 14:10
  • 2
    I gave you an upvote for this, I do understand that you are new to C++, but using `std::to_string()` is not really efficient to print `char`. –  Jun 15 '20 at 14:57
0

In addition to the answers to your question, you can check whether your value is printable or not by using isprint().

std::cout << isprint(lottoGlueck) << std::endl;

This will print 0 (false) if your value is non-printable.

Sercan
  • 2,081
  • 2
  • 10
  • 23
  • 2
    Nice catch, but I think it should be a comment, not an answer (since it doesn't answer the actual question) – Fareanor Jun 15 '20 at 14:00
  • I am sorry, I am new here, should i delete this and add as comment? – Sercan Jun 15 '20 at 14:01
  • Don't be sorry, no problem mate :) I can't tell what you should do, but I can tell that if I were you, I would delete the answer and post it as a comment (since this is a relevant comment in my opinion). – Fareanor Jun 15 '20 at 14:02
  • I tried but turned out I could not add comment until I have 50 reputation :) – Sercan Jun 15 '20 at 14:05
  • Oh right I forgot about this rule. Let it be as it is then, my bad ^^ – Fareanor Jun 15 '20 at 14:06