我在读取未知大小的标准输入时遇到问题。实际上它是.txt文件中的一个表,我通过调用参数'<'table.txt来获取stdin。我的代码应如下所示:
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
char words[10][1024];
int i=0;
while(feof(stdin)==0)
{
fgets(words[i],100,stdin);
printf("%s", words[i]);
i++;
}
return 0;
}
但有问题我不知道行的nuber,在这种情况下是10(我们知道行中的字符数 - 1024)。 如果有人知道解决方案会很棒。提前谢谢。
答案 0 :(得分:2)
我建议您使用malloc
和realloc
来管理您的记忆。跟踪数组的大小或它有多少条目,并在数组不够大时调用realloc
使其大小加倍。
答案 1 :(得分:2)
你遇到了困扰所有新C程序员的问题之一。我如何动态分配我需要的所有内存,让自己从静态限制中解脱出来,同时仍然跟踪我在内存中收集的“东西”。当您需要从输入中读取未知数量的“事物”时,通常会出现此问题。最初的选项是(1)声明一些足够大的限制可以工作(达不到目的),或(2)根据需要动态分配指针。
显然,目标是(2)。然而,你遇到了“如何跟踪我分配的内容?”的问题。这本身就是狗初学者的问题。问题是,如果我使用一堆指针动态分配,**我如何遍历列表以使我的'东西'退出?此外,你必须初始化一些初始指针数(除非使用像链接列表这样的高级数据结构),所以下一个问题是“当我用完时该怎么办?”
通常的解决方案是分配一组初始指针,然后当达到限制时,重新分配到原始指针的两倍,然后继续。 (正如格雷森在答案中指出的那样)。
但是,还有一个技巧可以迭代列表以让你的'东西'退出,这是值得理解的。是的,您可以使用malloc
进行分配并跟踪所使用的指针数量,但您可以通过最初使用{{1}进行分配,将自己从计数器绑定到指针列表中解放出来}。这不仅可以分配空间,还可以将分配的指针设置为calloc
(或0)。这允许您使用简单的NULL
迭代列表。当将指针集合传递给函数等时,这提供了许多好处。缺点(最小的一点)是您可以编写使用while (pointer != NULL)
的重新分配方案在需要时分配新空间。 (让我变得更聪明 - 但我必须努力做到这一点......)
您可以评估是否使用现成的calloc
,或者是否使用malloc/realloc
和calloc
重新分配,具体取决于您的要求。无论如何,理解两者,只需在编程工具箱中添加更多工具。
好的,足够的jabber,这一切的例子在哪里?
以下两个示例都只读取任何文本文件中的所有行,并将行(带指针索引号)打印回stdout。两者都希望您提供文件名作为命令行上的第一个参数。两者之间的唯一区别是第二个是custom reallocate function
完成的重新分配是calloc
。它们最初都会分配custom reallocation function
个指针,每次达到限制时指针的数量都会增加一倍。 (为了好玩,您可以将255
设置为像MAXLINES
这样的小事,并强制重复重新分配以进行测试。
在main()
中重新分配的第一个示例10
自定义函数中重新分配的第二个示例
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#define MAXLINES 255
void free_buffer (char **buffer)
{
register int i = 0;
while (buffer[i])
{
free (buffer[i]);
i++;
}
free (buffer);
}
int main (int argc, char **argv) {
if (argc < 2) {
fprintf (stderr, "Error: insufficient input. Usage: %s input_file\n", argv[0]);
return 1;
}
char *line = NULL; /* forces getline to allocate space for buf */
ssize_t read = 0; /* number of characters read by getline */
size_t n = 0; /* limit number of chars to 'n', 0 no limit */
char **filebuf = NULL;
char **rtmp = NULL;
int linecnt = 0;
size_t limit = MAXLINES;
size_t newlim = 0;
FILE *ifp = fopen(argv[1],"r");
if (!ifp)
{
fprintf(stderr, "\nerror: failed to open file: '%s'\n\n", argv[1]);
return 1;
}
filebuf = calloc (MAXLINES, sizeof (*filebuf)); /* allocate MAXLINES pointers */
while ((read = getline (&line, &n, ifp)) != -1) /* read each line in file with getline */
{
if (line[read - 1] == 0xa) { line[read - 1] = 0; read--; } /* strip newline */
if (linecnt >= (limit - 1)) /* test if linecnt at limit, reallocate */
{
newlim = limit * 2; /* set new number of pointers to 2X old */
if ((rtmp = calloc (newlim, sizeof (*filebuf)))) /* calloc to set to NULL */
{
/* copy original filebuf to newly allocated rtmp */
if (memcpy (rtmp, filebuf, linecnt * sizeof (*filebuf)) == rtmp)
{
free (filebuf); /* free original filebuf */
filebuf = rtmp; /* set filebuf equal to new rtmp */
}
else
{
fprintf (stderr, "error: memcpy failed, exiting\n");
return 1;
}
}
else
{
fprintf (stderr, "error: rtmp allocation failed, exiting\n");
return 1;
}
limit = newlim; /* update limit to new limit */
}
filebuf[linecnt] = strdup (line); /* copy line (strdup allocates) */
linecnt++; /* increment linecnt */
}
fclose(ifp);
if (line) free (line); /* free memory allocated to line */
linecnt = 0; /* reset linecnt to iterate filebuf */
printf ("\nLines read in filebuf buffer:\n\n"); /* output all lines read */
while (filebuf[linecnt])
{
printf (" line[%d]: %s\n", linecnt, filebuf[linecnt]);
linecnt++;
}
printf ("\n");
free_buffer (filebuf); /* free memory allocated to filebuf */
return 0;
}
看看这两个例子。知道有很多很多方法可以做到这一点。这些示例仅提供一种方法,该方法提供了使用一些额外技巧的示例,而不是您通常会发现的。试一试。如果您需要更多帮助,请发表评论。
答案 2 :(得分:1)
Op似乎需要将数据存储在某处
#define N 100000u
char BABuffer[N];
int main(int argc, char *argv[]) {
size_t lcount = 0;
size_t ccount = 0;
char words[1024 + 2];
while(fgets(words, sizeof words, stdin) != NULL) {
size_t len = strlen(words);
if (ccount + len >= N - 1) {
fputs("Too much!\n", stderr);
break;
}
memcpy(&BABuffer[ccount], words, len);
ccount += len;
lcount++;
}
BABuffer[ccount] = '\0';
printf("Read %zu lines.\n", lcount);
printf("Read %zu char.\n", ccount);
fputs(BABuffer, stdout);
return 0;
}
注意:ccount
包含行尾字符。