Scanf未知数量的字符串参数C.

时间:2016-12-17 03:39:15

标签: c arrays char scanf

我想知道是否有办法使用scanf,因此我可以接收未知数量的字符串参数并将它们放入char*数组中。我已经看到它使用int值完成,但无法找到使用char数组完成的方法。参数也在由空格分隔的同一行上输入。

实施例: 用户输入hello goodbye yeshello存储在array[0]中,goodbye存储在array[1]中,yes存储在array[2]中。或者用户只需输入hello,然后数组中唯一的内容就是hello

我真的没有任何代码可以发布,因为我不知道如何做到这一点。

3 个答案:

答案 0 :(得分:3)

你可以这样做,直到“\ n”:

scanf("%[^\n]",buffer);

你需要事先分配一个足够大的缓冲区。

现在通过缓冲区计算单词数,并分配必要的空间char **array = ....dynamic string allocation),转到缓冲区并按字符串将字符串复制到数组中。

一个例子:

int words = 1;
char buffer[128];
int result = scanf("%127[^\n]",buffer);

if(result > 0)
{
    char **array;

    for(int i = 0; buffer[i]!='\0'; i++)
    {
       if(buffer[i]==' ' || buffer[i]=='\n' || buffer[i]=='\t')
       {
        words++;
       }
    }

   array = malloc(words * sizeof(char*));

   // Using RoadRunner suggestion
  array[0] = strtok (buffer," ");
  for(int w = 1; w < words; w++)
  {
     array[w] = strtok (NULL," ");
  }
}

如评论中所述,您应该使用(如果可以)fgets而不是fgets(buffer,128,stdin);。 有关strtok

的更多信息

答案 1 :(得分:2)

如果您有可能从用户收到的字符串数量的上限,以及每个字符串中的字符数,并且所有字符串都在一行中输入,则可以通过以下步骤执行此操作:

  • 使用fgets()
  • 阅读整行
  • 使用sscanf()解析包含最大%s转换说明符数的格式字符串的行。

以下是最多10个字符串的示例,每个字符串最多32个字符:

    char buf[400];
    char s[10][32 + 1];
    int n = 0;

    if (fgets(buf, sizeof buf, sdtin)) {
        n = sscanf("%32s%32s%32s%32s%32s%32s%32s%32s%32s%32s",
                   s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]));
    }
    // `n` contains the number of strings
    // s[0], s[1]... contain the strings

如果不知道最大数字是否未修复单个字符串的最大长度,或者如果可以在连续的行上输入字符串,则需要使用简单的循环进行迭代:

    char buf[200];
    char **s = NULL;
    int n;

    while (scanf("%199s", buf) == 1) {
        char **s1 = realloc(s, (n + 1) * sizeof(*s));
        if (s1 == NULL || (s1[n] = strdup(buf)) == NULL) {
            printf("allocation error");
            exit(1);
        }
        s = s1;
        n++;
    }
    // `n` contains the number of strings
    // s[0], s[1]... contain pointers to the strings

除了错误处理之外,此循环与上面的硬编码示例相当,但它仍然具有每个字符串的最大长度。除非您可以使用scanf()扩展名自动分配字符串(%as在GNU系统上),否则处理任意数量的字符串会变得更加复杂。

答案 2 :(得分:1)

您可以使用:

  • fgets来读取用户的输入。您可以更轻松地使用此代替scanf
  • malloc为堆上的指针分配内存。您可以使用起始大小,如下例所示:

    size_t currsize = 10
    char **strings = malloc(currsize * sizeof(*strings)); /* always check
                                                             return value */
    

    当超出空间时,根据需要增加realloc个空间:

    currsize *= 2;
    strings = realloc(strings, currsize * sizeof(*strings)); /* always check
                                                                return value */
    
  • 使用malloc()realloc()中请求的内存完成后,它总是对free指针结尾。

  • strtok解析每个空格的输入。复制来自char *的{​​{1}}指针时,您还必须使用strtok()strdupstrings[i]分配空间。

这是我前一段时间写的一个例子,它与你想要的东西非常相似:

malloc()