【问题标题】:How to create an array of 100 random strings in C如何在 C 中创建一个包含 100 个随机字符串的数组
【发布时间】:2018-04-14 07:40:49
【问题描述】:

我正在尝试在 C 中创建一个包含 100 个随机大小的字符串的数组,长度在 3 到 10 个字母之间,但我遇到了一些麻烦。这就是我目前所拥有的......

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]);
    }
}

我得到的输出是这样的......

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

任何帮助或指导将不胜感激。

【问题讨论】:

  • 尝试printf("%d\n", &amp;randomWord[count]); 使用 %s 而不是 %d,但请确保之前的字符串以零结尾。
  • 你认为&amp;randomWord[count]是什么?

标签: c arrays string random malloc


【解决方案1】:

首先,你肯定知道,你不写randomWord[count],这样你以后就不能打印出结果了。

其次,您需要用\0 终止每个字符串,并且应该使用printf("%s\n", randomWord[count]);,即不带&amp; 和带%s。不终止字符串并在printf("%s"... 中使用它很可能会产生未定义的行为;打印字符串时,使用%s,而不是%d。而当使用%s 时,printf 需要一个指向字符串第一个字符的指针。正如您定义的char *randomWord[100]randomWord[count] 代表这样一个指向字符的指针,而&amp;randomWord[count] 代表指针的地址,而不是字符串的第一个字符。

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]);

顺便说一句:请注意,(rand() % 10) + 3) 给出的随机长度介于 312 之间,而不是介于 310 之间。

【讨论】:

  • 您可能还想进一步评论&amp;randomWord[count] 的错误程度以及它的实际作用。
  • @David C. Rankin:完成。希望对 OP 有所帮助。
  • 干得好。这真是太不可思议了,表明对正在发生的事情有明显的误解。我相信它会有所帮助。放任这种误解是非常危险的......(更不用说通过使用%d 打印指针地址来调用的Undefined Behavior)......
【解决方案2】:

有多个问题:

  • 您没有将字符存储到分配的数组中。
  • 您计算的一个随机字母太少,从 0 开始循环可以解决此问题。
  • 您不打印单词,而只打印它们的地址。

以下是修复代码的方法:

#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;
}

【讨论】:

    【解决方案3】:

    您实际上使用了错误的格式说明符:

    %d 用于输出带符号的十进制整数。
    %c 用于输出字符。

    你内心的printf应该变成:printf("%c\n", randomLetter)

    【讨论】:

      【解决方案4】:

      我不会耕种其他答案耕种的相同土地。你现在明白了:

      printf("%d\n", &randomWord[count]);
      

      正在尝试打印 指针的地址 randomWord[count],而不是您尝试打印 ASCII 值的字符。请记住&amp;地址 一元运算符,而*取消引用 运算符。 (通过尝试使用%d 格式说明符打印指针地址来调用未定义行为。使用%p 打印地址)

      与其从 运算中发明每个字符,不如简单地从文字 A-Za-z0-9(或您希望包含的任何字符集)中选择一个随机索引可能更容易。这实际上是“六比一”和“六比一”,但从概念上讲,跟踪您正在做的事情可能更容易。

      在寻找替代方案之前,让我们在您的代码中使用幻数。 (不要这样做)。如果您需要在代码中使用常量,那么 #define 它们或使用全局 enum 来做同样的事情。例如,如果您需要生成字符串的最小长度常量(比如MINL)和最大长度MAXL 或最大字符串数MAXS(以及要生成的字符数)从NCHR) 中选择,您可以简单地定义常量:

      enum { MINL = 3, MAXL = 10, NCHR = 62, MAXS = 100 };
      

      这样,您可以在代码顶部有一个方便的位置来根据需要调整值 - 无需通过变量和循环声明来进行调整。

      现在是替代方案。您可以简单地声明一个字符串文字alpha,其中包含您希望从中创建100 随机字符串的字符。然后所需要做的就是为每个获取随机长度,分配length + 1 字节的存储空间,并在0NCHR - 1 之间创建length 随机数,将字符分配给字符串中的索引并进行空终止最后。

      (注意:通过使用calloc,您已经用零填充每个字符串中的最后一个字节,有效地提供了nul终止,但是肯定地nul终止每个字符串是一个好习惯字符串)

      总而言之,您可以执行以下操作:

      #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;
      }
      

      使用/输出示例

      $ ./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
      

      查看所有答案。有很好的观点。如果您还有其他问题,请告诉我们。

      【讨论】:

        猜你喜欢
        • 2016-09-23
        • 2011-08-06
        • 1970-01-01
        • 2015-05-12
        • 2022-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-21
        相关资源
        最近更新 更多