I'm new to C and trying to write a command line application that does a whole host of things based on the user input. I need to run the program on an infinite loop and read user input into a string array.
I've used the while loop to write it into a string.
while(fgets(str, 256, stdin)){
}
Now I'm a little confused about how to modify this loop to write strings into an array directly using space as a delimiter.
So if I've an input
Terminate client 2345
The array should have 3 elements with the first being Terminate. Any help appreciated.
答案 0 :(得分:3)
无论您是从stdin
读取还是从文件中读取,该过程基本相同。您可以使用面向行的输入(fgets
或getline
)阅读每一行,也可以使用面向字符的输入(getchar
,fgetc
等)。 (scanf
家族在中间)。阅读行时,通常最好的选择是面向行的输入。
当将用户输入读入数组时,您有两种选择,要么声明一个静态指针数组,并希望您分配足够的指针开始,要么动态根据需要分配指针数组realloc
以保存所有输入。 (谁知道,用户可能会重定向文件以供阅读)。当您动态分配任何内容时,您负责跟踪其使用,保留指向内存块原始起始地址的指针,并在不再需要时free
内存。
以下是从stdin
获取输入并将其存储在动态分配的数组中的标准示例。有一个扭曲。代码可以处理来自文件或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.
重定向输入也很好。 E.g:
$ ./bin/getline_readstdin_dyn < dat/ll_replace_poem.txt
答案 1 :(得分:0)
At the risk of advising parse kludge, you have your read loop. Now use strtok
or sscanf
to parse string by tokens into storage variables. In this setup I suspect strdup
is the better choice.