-2

I am making a bus reservation program. I want to give random hex numbers to the buses. How can i hold it in an array? in C

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

char rand_hex_string()
{
  //hexadecimal characters
  char hex_characters[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  return (char) hex_characters[rand()%16];
}


int main(int argc, char *argv[]) {
    srand(time(NULL));
    char busNo[6] = { '3', '7' , rand_hex_string() , rand_hex_string(), rand_hex_string(), rand_hex_string()};

printf("%s", busNo);

return 0;
}

I can print them all side by side but I cannot assign them all to an array.

For example, a number called 37604F was created. I want the first element of an array to be 37604F.

I want to assign a randomly generated 6-digit hexadecimal number starting with 37 to an array as a string. i dont know C very well

Emre
  • 11
  • 3
  • C++ or C? Pick one. The cast in `return (char)` is pointless. What kind of array do you want, to use where? Anyway, as a general hint, multidimensional arrays are a thing that exists, as are strings, and if you pick C++ then this is especially easy thanks to `std::string` and `std::vector`. – underscore_d Jan 14 '21 at 10:42
  • 1
    You need an array of 7 `char` to store a string of 6 characters, but then your program works for me: https://ideone.com/zJaEki – mch Jan 14 '21 at 10:43
  • What exactly do you want to do? If it's just filling an array with char's, then you can use [std::generate](https://en.cppreference.com/w/cpp/algorithm/generate). Also, in C++, you wouldn't use `printf`, but `std::out`. And `static_cast` instead of C-style casts(which, it your example, is completely pointless anyways). – Nikita Demodov Jan 14 '21 at 10:45
  • For example, a number called 37604F was created. I want the first element of an array to be 37604F. like array[0] = '37604F'; in C please. – Emre Jan 14 '21 at 10:48
  • `char array[N][6]; array[0] = busNo;`?? – Nikita Demodov Jan 14 '21 at 10:50
  • when i try char array[0] = busNo; it says invalid initializer. – Emre Jan 14 '21 at 10:53
  • 1
    You seem to be going around the hills to do something simple such as `int busnum = 1 + rand() % MAXNUM; printf("%X", busnum);` If you want a specific number of digits that needs a slight tweak. If you want an array of bus numbers then `int buses[NUM_BUSES];`. – Weather Vane Jan 14 '21 at 10:54
  • What datatype do you want? A `char` cannot hold `'37604F'`, a `char` can hold `'3'`, a `char [7]` can hold `"37604F"`. An `unsigned int` can hold `0x37604F`. – mch Jan 14 '21 at 10:55
  • i want "37604F" – Emre Jan 14 '21 at 10:57
  • Then `int busnum = 0x37604F; printf("%X", busnum);` or if you want it as a string then `sprintf(str, "%X", busnum);` – Weather Vane Jan 14 '21 at 10:58
  • i don't know c very well sorry. I want to assign a randomly generated 6-digit hexadecimal number starting with 37 to an array as a string. – Emre Jan 14 '21 at 11:04
  • `int num = 0x370000 + rand() % 0x10000; sprintf(str, "%X", num);` – Weather Vane Jan 14 '21 at 11:19
  • Thank you. it works but lastly https://ideone.com/HhAqfd why its ? – Emre Jan 14 '21 at 11:35
  • Change `str[0]=sprintf(str, "%X", num);` to `sprintf(str, "%X", num);` You were creating the string, and then overwriting the first digit with a non-printing value. – Weather Vane Jan 14 '21 at 11:38

1 Answers1

2

UPDATE

The code in my old answer isn't very efficient, but was very easy to understand and to implement. If you need to run the code on non-unix systems, or you can't access /dev/urandom, and need a more performant code this is probably the best answer.

Please note that rand_buf() I tried to code was worse then this function most of the times, so I decided to just copy-paste it.

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#if RAND_MAX == 0x7FFF
#define RAND_MAX_BITS 15
#elif RAND_MAX == 0x7FFFFFFF
#define RAND_MAX_BITS 31
#else
#error TBD code
#endif

#define byte unsigned char

#define MAX_BUS 32

//https://stackoverflow.com/a/50820616/9373031
//Queues leftover bits to optimize rand() 15 bits usage
void rand_buf(byte *dest, size_t size) {

    int r;
    int r_queue = 0;
    int r_bit_count = 0;

    for (size_t i = 0; i < size; i++) {
        r = 0;
        //printf("%3zu %2d %8x\n", i, r_bit_count, r_queue);
        if (r_bit_count < 8) {
            int need = 8 - r_bit_count;
            r = r_queue << need;
            r_queue = rand();
            r ^= r_queue;  // OK to flip bits already saved in `r`
            r_queue >>= need;
            r_bit_count = RAND_MAX_BITS - need;
        } else {
            r = r_queue;
            r_queue >>= 8;
            r_bit_count -= 8;
        }
        dest[i] = r;
    }

}

int main(int argc, char *argv[]) {

    srand(time(NULL));

    byte * rbuf = malloc(MAX_BUS*2);
    char buses[MAX_BUS][7];

    rand_buf(rbuf, MAX_BUS*2);

    for (int i = 0; i < MAX_BUS; i++) {

        sprintf(buses[i], "37%02X%02X", rbuf[i*2], rbuf[i*2 + 1]);
        //printf("%d = %s\n", i, buses[i]);

    }

    return 0;
}

rand_buf() simply works by storing 7 leftover bits (rand() returns at least 15 bits) and using "recycle" them later on.

OLD ANSWER

I would suggest using a better name for your function. Also you might want to end the arrays with \0 to create proper C strings. If you don't do it printf("%s") will read the whole array

After that you have to choose a size for a new c-string array (char[MAX_BUS][6], where MAX_BUS is the number of buses you will need to store).

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

#define MAX_BUS 32

char rand_hex_char() {     //returns a char not a char* (aka c-string)
  //hexadecimal characters
  char hex_characters[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  return hex_characters[rand()%16];
}

int main(int argc, char *argv[]) {
    srand(time(NULL));

    char buses[MAX_BUS][7];

    for (int i = 0; i < MAX_BUS; i++) {
        buses[i][0] = '3';
        buses[i][1] = '7';
        for (int j = 0; j < 4 /*rand chars*/; j++)
            buses[i][j+2] = rand_hex_char();
        buses[i][6] = 0;
        printf("%d = %s\n", i, buses[i]);
    }

    printf("%s\n", buses[0]);   //access the first bus

    return 0;
}
DadiBit
  • 769
  • 10
  • 22
  • I'm glad to hear that! If you understood everything and don't need help anymore you should accept my answer with the green tick under the vote. – DadiBit Jan 14 '21 at 11:52
  • 1
    I think this is a fairly poor implementation. There's no need to call `rand()` 16 times or to keep a list of hexadecimal characters. The number of possibilities is 16^6, which is 16*16*16*16*16*16 or 256*256*256. You need to generate a single number between 0 and that number, and then use `snprintf` to format the number using `%x` or `%X`. On linux systems it's probably better to just read 3 bytes from /dev/urandom. – Cheatah Jan 14 '21 at 12:21
  • @Cheatah you're right! Right now I'm calling `rand()` `MAX_BUS*4` times and I am using `%` as well... The best implementation with `rand()` should be `ceil(MAX_BUS*16/15)` calls. `rand()` will returns at least 15 bits, btw. – DadiBit Jan 15 '21 at 12:22