1

I want to get a word from a random number of characters from a given set, but an error appears segmentation fault. How to get rid of it?

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

char* getrand() {
  char* symbols[] = {"a,", "b", "с", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
  char* letter;
  char* words;
  for (int i = 0; i < rand() % 10; i++) {
   letter = symbols[rand() % 26];
   words = strcat(letter, symbols[rand() % 26]);
  }
  return words;
}

int main(void) {
  srand(time(NULL));
  char* new_word;
  new_word = getrand();
  printf("%s\n", new_word);
  return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Rume One
  • 37
  • 3

2 Answers2

2

By allocating memory for your strings, either statically or dynamically (which your really don't need here, but for practice purposes only, I mention it).

You are overcomplicating things in my opinion. Assuming your words actually have letters (so "a," is a typo and you really meant to write "a"), then you could do this instead:

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

#define MAX_LEN 10
#define SYMBOLS_LEN 26

void getrand_word(char* word, int word_max_len) {
  char symbols[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
  char letter;
  for (int i = 0; i < rand() % word_max_len; i++) {
   letter = symbols[rand() % SYMBOLS_LEN];
   word[i] = letter;
  }
}

int main(void) {
  srand(time(NULL));
  char word[MAX_LEN] = {0};
  getrand_word(word, MAX_LEN);
  printf("%s\n", word);
  return 0;
}

Output:

cik

where I statically allocate a string array called word, of size MAX_LEN, equal to 10, since we know that at most we are going to randomly select a letter (symbol) 9 (10 - 1) times.

So our word can have at most 9 letters, but we need one more slot in our string array, in order for the NULL terminator to be stored into, thus we need our string array to be of size 10.

Then I pass this string array into getrand_word(), in order to get my string randomly populated.

In that method I have an array of characters (and not strings like in your example), because a symbol (letter) is a character, not a string.

The for loop will run at most (word_max_len - 1 times), since rand() % word_max_len produces integers into [0, word_max_len). There we randomly choose a number to index our symbols array. We want to be able to select any letter, from start to end, so we need rand() % SYMBOLS_LEN. Read more in How to generate a random int in C?

After choosing the letter, it sufficies to simply append it to the string, by using the loop counter as the string's index.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
1

I've made a few small modifications:

  • allocate storage for the word
  • free the allocated word after use
  • correct use of strcat
  • ensure that it won't generate zero-length words
  • fix typo in symbols initialiser
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

const int MAX_WORD = 10;

char *get_random_word(void) {
  const char *symbols[] = {
    "a", "b", "с", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
    "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
  };
  char *words = calloc(MAX_WORD + 1, sizeof(char));
  if (!words) {
    return NULL;
  }

  for (int ii = 0; ii < 1 + (rand() % MAX_WORD); ii++) {
    strcat(words, symbols[rand() % 26]);
  }

  return words;
}

int main(void) {
  srand(time(NULL));
  char *new_word = get_random_word();
  if (new_word) {
    printf("%s\n", new_word);
    free(new_word);
    return 0;
  } else {
     return 1;
  }
}
jarmod
  • 71,565
  • 16
  • 115
  • 122