【问题标题】:how to Read large input - 8MBdata in C如何读取大输入 - C 中的 8MB 数据
【发布时间】:2016-03-04 03:35:51
【问题描述】:

我有一个问题,我必须从输入文件中读取大数据(8mb)。我尝试给出数组的大小。有什么有效的方法可以重写代码

#include <stdio.h>
#include <stdlib.h>
int main()
 {

FILE *f;
char msg[9000000]=" ";  
int i=0;
f=fopen("file.txt","r");
while((msg[i]=fgetc(f))!=EOF){
        i++;
        }
 printf("\nThe data from the file is :%s\n",msg);
fclose(f);
return 0;
 }

【问题讨论】:

  • 只是不要将它存储在堆栈上,而是使用堆分配的内存。见mallocfree
  • 另请注意,虽然可移植性较差(POSIX 与 Windows 目标的不同 API),但当您尝试从文件中获取二进制数据时,内存映射通常很有帮助。在 Windows 上搜索 mmap(如果您使用 UNIX、Linux、BSD、OSX 等 POSIX 系统)或 CreateFileMapping;尤其是在 64 位机器的时代,当您可以 mmap 文件并像访问延迟填充的数组一样访问它时,几乎没有理由更喜欢显式的文件读/写 API。
  • static char msg[9000000]; 是一个简单的解决方案
  • msg[i]=fgetc(f))!=EOF 不正确(它要么永远不会触发,要么对某些字符给出误报)。您需要将fgetc 的结果存储在int 中并与EOF 进行比较。此循环还应检查它是否不会溢出msg 的范围。使用 fread 而不是循环将立即解决所有这些问题。

标签: c arrays input


【解决方案1】:

在这种情况下,您可以只写您读到的内容,而无需将所有内容保存在内存中。

#include <stdio.h>
#include <stdlib.h>
int main(void)
{

    FILE *f;
    int msg;
    int inputExists = 0;
    f=fopen("file.txt","r");
    if(f == NULL){
        perror("fopen");
        return 1;
    }
    printf("\nThe data from the file is :");
    while((msg=fgetc(f))!=EOF){
        putchar(msg);
        inputExists = 1;
    }
    if(!inputExists) putchar(' ');
    printf("\n");
    fclose(f);
    return 0;
}

【讨论】:

  • 您好,感谢您的回复。我试图永远运行代码及其循环
  • 感谢您的回复。 msg 有没有可能是一个数组
  • @tummalsr 无法在本地环境中重现“永远循环”。是的,msg 可以是经过适当代码修改的数组。你想对数组做什么?
  • scanf("%[^\n]%*c", msg[i]); for (i = 0; msg[i] != '\0'; i++) m[i] = msg[i]
  • 我正在尝试将 msg 保存在一个数组中,然后尝试将长度划分为块的大小。 len = strlen(味精);整数块大小 = 4; numBlocks = len / blocksize;
【解决方案2】:

非静态局部变量(通常,尽管 C 标准不要求)存储在堆栈中。在大多数系统中,该堆栈的大小相当有限,通常约为 1 MB 甚至更少。

因此,您应该将数据存储在其他位置,无论是在堆上还是在静态内存中。使用堆是首选方式:

#include <stdio.h>
#include <stdlib.h>
#define MAX (8 * 1024 * 1024)
int main () {
  char * data = malloc(MAX);
  // add error checks
  int in;
  size_t position = 0;
  while ((in = fgetc(stdin)) != EOF && position < MAX) {
    data[position++] = in & 0xFF;
  }
  // Note: data is NOT a string, no null termination
  // also check for errors
  free(data);
  return 0;
}

需要注意两点:我还在检查缓冲区是否不会溢出。这非常重要,您应该确保 每个 读取和写入的缓冲区。

其次,任何参考都会告诉你,fgetc 的返回值是int。这很重要,因为EOF 可能是一个无法用char 表示的值。

【讨论】:

  • "局部变量存储在堆栈中。"不,它们不需要存储在堆栈中。在典型实现中,非静态局部变量存储在堆栈中,而静态局部变量则不存储。
  • 确实,我大多忘记了静态的。这里很晚了:D @MikeCAT
猜你喜欢
  • 2016-05-17
  • 2013-02-11
  • 2018-06-07
  • 1970-01-01
  • 2022-07-21
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
相关资源
最近更新 更多