【问题标题】:Taking user input and storing it in an array of strings in C获取用户输入并将其存储在 C 中的字符串数组中
【发布时间】:2015-05-24 21:38:04
【问题描述】:

我是 C 新手,正在尝试编写一个命令行应用程序,该应用程序可以根据用户输入执行大量操作。我需要在无限循环上运行程序并将用户输入读入字符串数组。

我使用 while 循环将其写入字符串。

while(fgets(str, 256, stdin)){

}

现在我有点困惑如何修改这个循环以直接使用空格作为分隔符将字符串写入数组。

如果我有意见

Terminate client 2345

数组应该有 3 个元素,第一个元素是 Terminate。任何帮助表示赞赏。

【问题讨论】:

标签: c arrays


【解决方案1】:

无论是从stdin读取还是从文件读取,过程基本相同。您可以使用 line-oriented 输入(fgetsgetline)读取每一行,或者使用 character-oriented 输入(getcharfgetc 等)。 (scanf 家族位于中间)。阅读lines时,一般来说最好的选择是line-oriented输入。

在将用户输入读入数组时,您有两种选择,要么声明一个静态指针数组并希望分配足够多的指针开始,要么动态根据需要分配指针数组和realloc 以保存所有输入。 (谁知道,用户可能会重定向文件以供阅读)。当您动态分配任何内容时,有责任跟踪其使用情况,保留指向内存块原始起始地址的指针,并在不再需要内存时freeing 内存。 p>

以下是从stdin 获取输入并将其存储在动态分配的数组中的标准示例。有一个转折。该代码可以处理来自文件stdin 的输入。如果文件名作为第一个参数给出,那么它将读取文件,否则从标准输入读取。它希望用户提供所需的尽可能多的输入,然后在完成后按[ctrl+d]。 (手动生成EOF)。

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

#define NMAX 128

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

    char *ln = NULL;                /* NULL forces getline to allocate  */
    size_t n = 0;                   /* initial ln size, getline decides */
    ssize_t nchr = 0;               /* number of chars actually read    */
    size_t idx = 0;                 /* array index counter              */
    size_t nmax = NMAX;             /* check for reallocation           */
    char **array = NULL;            /* array to hold lines read         */
    FILE *fp = NULL;                /* file pointer to open file fn     */

    if (argc > 1) {
        if (!(fp = fopen (argv[1], "r"))) {
            fprintf (stderr, "error: file open failed for '%s'\n", argv[1]);
            return 1;
        }
    }
    else
        fp = stdin;

    /* allocate NMAX pointers to char* */
    if (!(array = calloc (NMAX, sizeof *array))) {
        fprintf (stderr, "error: memory allocation failed.");
        return 1;
    }

    if (fp == stdin)
        printf ("\nEnter information to store in array on each line, [ctrl+d] when done:\n\n");

    /* read each line from file or stdin - dynamicallly allocated   */
    while ((nchr = getline (&ln, &n, fp)) != -1)
    {
        /* strip newline or carriage rtn    */
        while (nchr > 0 && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r'))
            ln[--nchr] = 0;

        array[idx] = strdup (ln);   /* allocate/copy ln to array        */

        idx++;                      /* increment value at index         */

        if (idx == nmax) {          /* if lines exceed nmax, reallocate */
            char **tmp = realloc (array, nmax * 2 * sizeof *tmp);
            if (!tmp) {
                fprintf (stderr, "error: memory exhausted.\n");
                break;
            }
            array = tmp;
            nmax *= 2;
        }
    }

    if (ln) free (ln);              /* free memory allocated by getline */
    if (fp != stdin) fclose (fp);   /* close open file descriptor       */

    size_t i = 0;

    /* print array */
    printf ("\nThe lines in the file are:\n\n");
    for (i = 0; i < idx; i++)
        printf (" line[%3zu] : %s\n", i, array[i]);

    /* free array */
    for (i = 0; i < idx; i++)
        free (array[i]);
    free (array);

    return 0;
}

示例/输出

$ ./bin/getline_readstdin_dyn

Enter information to store in array on each line, [ctrl+d] when done:

This is a line of input
This is another
and another
etc..

The lines in the file are:

 line[  0] : This is a line of input
 line[  1] : This is another
 line[  2] : and another
 line[  3] : etc..

或者从文件中读取:

$ ./bin/getline_readstdin_dyn dat/ll_replace_poem.txt

The lines in the file are:

 line[  0] : Eye have a spelling chequer,
 line[  1] : It came with my Pea Sea.
 line[  2] : It plane lee marks four my revue,
 line[  3] : Miss Steaks I can knot sea.
 line[  4] : Eye strike the quays and type a whirred,
 line[  5] : And weight four it two say,
 line[  6] : Weather eye am write oar wrong,
 line[  7] : It tells me straight aweigh.
 line[  8] : Eye ran this poem threw it,
 line[  9] : Your shore real glad two no.
 line[ 10] : Its vary polished in its weigh.
 line[ 11] : My chequer tolled me sew.
 line[ 12] : A chequer is a bless thing,
 line[ 13] : It freeze yew lodes of thyme.
 line[ 14] : It helps me right all stiles of righting,
 line[ 15] : And aides me when eye rime.
 line[ 16] : Each frays come posed up on my screen,
 line[ 17] : Eye trussed too bee a joule.
 line[ 18] : The chequer pours over every word,
 line[ 19] : Two cheque sum spelling rule.

重定向输入也很好。例如:

$ ./bin/getline_readstdin_dyn < dat/ll_replace_poem.txt

【讨论】:

    【解决方案2】:

    冒着建议 parse kludge 的风险,你有你的读取循环。现在使用strtoksscanf 将字符串按标记解析为存储变量。在这个设置中,我怀疑strdup 是更好的选择。

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多