Reputation: 15
I'm trying to create an array of 100 strings of random sizes between 3 and 10 letters long in C but I'm having a bit of trouble. This is what I have so far...
int main() {
int count, number;
char *randomWord[100]; // 1-d array of pointers to char
char randomLetter;
int wordLength;
// generate 100 strings or random sizes between 3 and 10 letters
for (count = 0; count < 100; count++) {
wordLength = ((rand() % 10) + 3); // get random size of word
randomWord[count] = malloc(wordLength + 1); // allocated space for word
for (number = 1; number < wordLength; number++) {
randomLetter = 'A' + (rand() % 26);
//randomWord[count] =
printf("%d\n", randomLetter);
}
printf("%d\n", &randomWord[count]);
}
}
The output I get looks like this...
72
90
82
73
87
75
66
65
6356712
88
66
71
70
67
66
67
69
89
72
74
6356716
71
73
88
87
6356720
Any help or direction would be appreciated.
Upvotes: 1
Views: 2089
Reputation: 144540
There are multiple problems:
0
would fix this.Here is how to fix the code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int count, number;
char *randomWord[100]; // 1-d array of pointers to char
// generate 100 strings or random sizes between 3 and 10 letters
for (count = 0; count < 100; count++) {
int wordLength = 3 + rand() % 8; // get random word size in 3..10
randomWord[count] = malloc(wordLength + 1); // allocated space for word
for (number = 0; number < wordLength; number++) {
randomWord[count][number] = 'A' + rand() % 26;
}
randomWord[count][number] = '\0';
printf("%s\n", randomWord[count]);
}
return 0;
}
Upvotes: 0
Reputation: 84521
I won't plow the same ground plowed by the other answers. You now understand that:
printf("%d\n", &randomWord[count]);
was attempting to print the address of the pointer randomWord[count]
and not at all the character you were attempting to print the ASCII value of. Remember &
is the address of unary operator while *
is the dereference operator. (which was invoking Undefined Behavior by attempting to print a pointer address with the %d
format specifier. Use %p
to print addresses)
Rather than invent each character from a modulo operation, it may be easier to simply pick a random index from a literal A-Za-z0-9
(or whatever character set you wish to include). It is really "six to one" a "half-dozen to another", but it may be conceptually easier to keep track of what you are doing.
Before looking at an alternative, let's address using magic numbers in your code. (don't do it). If you need constants for use in your code, then #define
them or use a global enum
to do the same. For example, if you need constants for the minimum length of string to generate (say MINL
) and max length MAXL
or the maximum number of strings MAXS
(and the number of characters to choose from NCHR
), you can simply define constants with:
enum { MINL = 3, MAXL = 10, NCHR = 62, MAXS = 100 };
That way you have a single convenient location at the top of your code to adjust values as required -- without having to pick through your variable and loop declarations to do it.
Now the alternative. You can simply declare a string literal alpha
with the characters you wish to create 100
random strings from. Then all that is required is to get a random length for each, allocate length + 1
bytes of storage, and create length
random numbers between 0
and NCHR - 1
assigning the character to the indexes in your string and nul-terminating at the end.
(note: by using calloc
, you have already filled the final byte in each string with zero, effectively providing for nul-termination, but it is good practice to affirmatively nul-terminate each string)
Putting that altogether, you could do something like the following:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum { MINL = 3, MAXL = 10, NCHR = 62, MAXS = 100 };
int main (void) {
char *alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* NCHR long literal */
"abcdefghijklmnopqrstuvwxyz" /* of chars to shuffle */
"0123456789",
*a[MAXS] = { NULL }; /* array of pointers to char */
int modlen = MAXL - MINL + 1; /* mod length for 3 - 10 char */
srand (time (NULL)); /* seed random number generator */
for (int i = 0; i < MAXS; i++) { /* loop to create MAXS strings */
int len = rand() % modlen + MINL; /* get length 3 - 10 */
if (!(a[i] = calloc (len + 1, 1))) { /* allocate memory */
fprintf (stderr, "error: memory exhausted 'a[%d]'.\n", i);
return 1;
}
for (int j = 0; j < len; j++) /* loop over len chars */
a[i][j] = alpha[rand() % NCHR]; /* assing char from alpha */
a[i][len] = 0; /* affirmatively nul-terminate */
}
for (int i = 0; i < MAXS; i++) { /* output results */
printf ("a[%2d] : %s\n", i, a[i]);
free (a[i]); /* don't forget to free your memory */
}
return 0;
}
Example Use/Output
$ ./bin/str_randshuffle
a[ 0] : KhwC0FhKv
a[ 1] : j4U4zwfHf
a[ 2] : vSd
a[ 3] : 4jWlzWJ725
a[ 4] : q9h
a[ 5] : sxYmHSZ1w
a[ 6] : WSPot
a[ 7] : hTD
a[ 8] : GXQ
a[ 9] : NJD3GksyYE
a[10] : dUvVGPrWe
....
a[92] : vHl5
a[93] : 5LZjkFYl
a[94] : Q4Y
a[95] : 67sWds
a[96] : YlQWDuFKV8
a[97] : PHJwrOLQ6b
a[98] : U0EPiarOi
a[99] : zyZ2gcB2aw
Look over all the answers. There are good points made. Then let us know if you have any further questions.
Upvotes: 0
Reputation: 35154
First, as you know for sure, you do not write into randomWord[count]
, such that you cannot print out the result later.
Second, you'd need to terminate each string with \0
, and you should use printf("%s\n", randomWord[count]);
, i.e. without the &
and with %s
. Not terminating a string and using it in printf("%s"...
very likely yields undefined behaviour; When printing a string, use %s
, not %d
. And when using %s
, printf
requires a pointer to the first character of the string. As you defined char *randomWord[100]
, randomWord[count]
stands for such a pointer to a character, whereas &randomWord[count]
would stand for the address of the pointer, not of the string's first character.
wordLength = ((rand() % 10) + 3); // get random size of word
randomWord[count] = malloc(wordLength + 1); // allocated space for word
for(number = 0; number < wordLength; number++)
{
randomLetter = 'A' + (rand() % 26);
randomWord[count][number] = randomLetter;
// printf("%c", randomLetter);
}
randomWord[count][wordLength] = '\0';
printf("%s\n", randomWord[count]);
BTW: Note that (rand() % 10) + 3)
gives random lengths between 3
and 12
, not between 3
and 10
.
Upvotes: 2
Reputation: 1249
You are actually using the wrong format specifier:
%d
is used to output a signed decimal integer.
%c
is used to output a character.
Your inner printf
should become : printf("%c\n", randomLetter)
Upvotes: 0