C语言中多次读取stdin及超大数字数组初始化方案咨询
这个问题问得很到位!我分两部分来给你解答——首先是能不能多次读取stdin,然后是如何处理位数不确定的超大数字数组:
一、能不能多次读取同一标准输入(stdin)?
默认情况下,stdin是单向的字节流——一旦你读取了流里的内容,这些内容就会被从流中移除,没办法直接“倒回去”重复读取。不过有个实用的解决办法:先把所有输入内容一次性读到内存缓冲区里(比如字符串或者动态数组),之后你就可以反复从这个内存缓冲区里取数据,相当于模拟了“多次读stdin”的效果。
如果你用的是类Unix系统,还有底层的dup()系统调用可以复制文件描述符,但这个对你的场景来说没必要,内存缓存的方法更简单直接。
二、处理超大数字+初始化数组的通用方案
因为数字位数不确定,没法提前固定数组大小,这里有两种靠谱的思路,都能实现通用的解决方案:
思路1:先统计总位数,再初始化数组
先把所有输入读进内存,统计清楚总共有多少位数字,再根据这个数量初始化数组,最后把内存里的数字字符转成int存进去。这种方法逻辑清晰,适合需要先知道总长度再做后续处理的场景。
举个C语言的实现例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char temp_buf[1024]; // 初始小缓冲区,不够会自动扩容 int total_digits = 0; char *all_digits = NULL; int read_len; // 第一步:读取所有输入,统计数字位数并缓存字符 while ((read_len = fread(temp_buf, 1, sizeof(temp_buf), stdin)) > 0) { for (int i = 0; i < read_len; i++) { if (temp_buf[i] >= '0' && temp_buf[i] <= '9') { total_digits++; // 动态扩容缓存区,存储当前数字字符 all_digits = realloc(all_digits, total_digits * sizeof(char)); all_digits[total_digits - 1] = temp_buf[i]; } } } if (total_digits == 0) { printf("没有输入有效数字!\n"); free(all_digits); return 1; } // 第二步:初始化数组,将字符转成int存入 int *digit_array = malloc(total_digits * sizeof(int)); for (int i = 0; i < total_digits; i++) { digit_array[i] = all_digits[i] - '0'; } // 这里可以用digit_array做后续处理 printf("总位数:%d\n第一位:%d\n最后一位:%d\n", total_digits, digit_array[0], digit_array[total_digits-1]); // 记得释放内存,避免泄漏 free(all_digits); free(digit_array); return 0; }
思路2:边读边动态扩容数组
不需要提前统计位数,每读到一个有效数字就把数组扩容一位,直接把数字存进去。这种方法更高效,少了一次“缓存字符再转数组”的步骤。
同样用C语言示例:
#include <stdio.h> #include <stdlib.h> int main() { int *digit_array = NULL; int current_count = 0; int c; // 逐个读取输入字符,只处理数字 while ((c = getchar()) != EOF) { if (c >= '0' && c <= '9') { current_count++; // 动态扩容数组 digit_array = realloc(digit_array, current_count * sizeof(int)); digit_array[current_count - 1] = c - '0'; } } if (current_count == 0) { printf("没有输入有效数字!\n"); free(digit_array); return 1; } printf("总位数:%d\n第一位:%d\n最后一位:%d\n", current_count, digit_array[0], digit_array[current_count-1]); free(digit_array); return 0; }
如果用Python的话就更简单了
Python的列表本身就是动态扩容的,直接把输入读成字符串再转成列表就行,完全不用手动管理内存:
import sys # 读取所有输入,过滤掉非数字字符 digits_str = ''.join([c for c in sys.stdin.read() if c.isdigit()]) digit_array = [int(c) for c in digits_str] print(f"总位数:{len(digit_array)}") if digit_array: print(f"第一位:{digit_array[0]},最后一位:{digit_array[-1]}")
内容的提问来源于stack exchange,提问作者victory
相关产品推荐
相关产品推荐

