【问题标题】:Reading the same input multiple times - C多次读取相同的输入 - C
【发布时间】:2018-09-08 23:32:34
【问题描述】:

我想问你是否可以多次读取相同的输入(stdin)?我即将得到一个非常大的数字,包含数千位数字(所以我无法将它存储在变量中,(而且我也不能使用文件夹!)。我的想法是将数字放入 int 数组中,但我没有不知道数组应该有多大,因为输入的位数可能会有所不同。我必须编写通用解决方案。 所以我的问题是,在将数字复制到数组之前,如何解决它,以及如何找出数字的数量(以便我可以初始化数组)。我尝试多次使用 scanf() 或 scanf() 和 getchar,但它不起作用。查看我的代码:

int main(){
int c;
int amountOfDigits=5;
while(scanf("%1d",&c)!=' '){//finding out number of digits with scanf
    if(isdigit(c)==0){
        break;
    }
    amountOfDigits++;
}

int digits[amountOfDigits];//now i know lenght of array, and initialize it
for(int i=0;i<amountOfDigits;i++){//putting digits into array
    digits[i]=getchar();
}

for(int i=0;i<amountOfDigits;i++){//printing array
    printf("%d",digits[i]);
}
printf("\n");

return 0;
}

【问题讨论】:

  • 分配一些内存。阅读fgets。如果输入不以换行符结尾,则重新定位内存并重复(读入前一个字符串结尾)。我确定有重复。
  • 不,一般来说你不能重读输入。正如 Weather Vane 所提到的,通常的事情是 malloc 然后 realloc 一些内存,随着您阅读越来越多的输入,数组越来越大。或者,在许多系统上,有一个库函数 getline 会自动为您执行此操作。
  • 你必须使用动态分配:malloc() / realloc()。
  • 但是,如果你在 Linux 上,如果信息被重定向到你的程序,你可以使用STDIN_FILENOmmap 输入流。

标签: c arrays input integer


【解决方案1】:

是否可以多次读取相同的输入(stdin)?

(我猜你是开始learn编程的学生,并且你正在使用Linux;如果不是,请调整我的答案)

对于您的家庭作业,您无需多次阅读相同的输入。在某些情况下,这是可能的(当标准输入是真正的文件 -seekable- 时,即当您在命令中使用一些 redirection 时)。在其他情况下(例如,当标准输入是管道时,例如使用command pipeline;或在您的shell 命令中使用here documents...)不可能多次读取stdin(但你不需要)。一般来说,不要指望stdin 可以与fseekrewind 一起搜索(通常不是)。

(我不会做你的功课,但这里有一些有用的提示)

所以我无法将它存储在变量中,(而且我也不能使用文件夹!)

你可以做几件事:

  • (因为您提到了文件夹......)您可能会使用一些更复杂的方式在磁盘上存储数据(但在您的特定情况下,我不建议这样做。 ..)。这些方式可能是一些直接访问的文件(丑陋),或者一些索引文件à la gdbm,或一些数据库à la sqlite 甚至一些RDBMS 服务器,如PostGreSQL
    就您而言,您不需要任何这些;我之所以提到它,是因为您提到了“文件夹”,而您的意思是“directories”!

  • 您确实应该使用一些堆分配的内存,因此请阅读C dynamic memory allocation仔细阅读每个标准memory management functions 的文档,例如mallocreallocfree。您的程序可能应该使用所有这三个函数(不要忘记 mallocrealloc 可能会失败)。

阅读thisthat 的答案。两者都具有惊人的相关性。

您可能应该以某种方式保留:

  1. 一个指向堆分配的指针int-s(实际上,你可以使用char-s)

  2. 该指针的分配大小

  3. 那个东西的使用长度,也就是实际有用的位数。

您当然不想通过在每个循环中重复 realloc 来增加您的数组(这是低效的)。在实践中,您会采用一些不断增长的方案,例如 newsize = 3*oldsize/2 + 10,以避免在(输入循环的)每一步重新分配内存。

你应该感谢你的老师做了这么有用的练习,但你不应该指望 StackOverflow 做你的功课!


还要注意arbitrary-precision arithmetic(称为 bignums 或 bigints)。实际上很难高效地编码,所以在现实生活中你会使用像GMPlib 这样的库。

【讨论】:

  • 感谢您的回复,您能否解释一下为什么我不应该经常调用 calloc(在每个循环中)?我不想创建超出必要的空间。
  • 效率低下。而且内存很便宜。您当然可以承受“丢失” 25% 的内存。所以你应该(在实践中)创造比必要更多的空间。当然,当您编写处理 TB 数据的程序时,您的关注点会大不相同。顺便说一句,不要忘记开发人员的时间(您花在代码上的时间)也很昂贵(而且通常比运行程序的硬件成本更高)。
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
相关资源
最近更新 更多