所提供的代码从文本文件中读取行,并将它们存储在动态分配的称为行的2D数组中(该模式总是在第32767行之后重复).然后,它连接特定的行(行[j]、行[k]、行[m]),并在输出文件中打印结果.问题是我的input.txt文件太大了,以至于我的PC无法处理这个-100 GB.因为使用Malloc时,我为2D数组分配了如此多的内存,以至于我的硬盘驱动器已满.有没有可能更改我的代码,这样我就不必分配这么多内存了?谢谢你的帮助!

#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LENGTH 300          // specifies the maximum length of a line in the input file
#define MAX_LINES 500000000          // specifies the maximum number of lines of the input file

int main()
{
   // Open the file
   FILE *fp = fopen("input.txt", "r");
   if (fp == NULL)
   {
       printf("Failed to open the file.\n");
       return 1;
   }


   // Allocate memory for lines
   char **lines = (char **)malloc(MAX_LINES * sizeof(char *));
   if (lines == NULL)
   {
       printf("Failed to allocate memory for lines.\n");
       fclose(fp);
       return 1;
   }

   for (int i = 0; i < MAX_LINES; i++)
   {
       lines[i] = (char *)malloc(MAX_LINE_LENGTH * sizeof(char));
       if (lines[i] == NULL)
       {
           printf("Failed to allocate memory for line %d.\n", i);
           // Free previously allocated lines
           for (int j = 0; j < i; j++)
           {
               free(lines[j]);
           }
           free(lines);
           fclose(fp);
           return 1;
       }
   }

   // Reset file pointer to the beginning
   fseek(fp, 0, SEEK_SET);

   // Read lines from the file and store them in lines array
   int lineIndex = 0;
   char line[MAX_LINE_LENGTH];
   while (fgets(line, sizeof(line), fp) != NULL)
   {
       // Remove newline character from the end of the line
       if (line[strlen(line) - 1] == '\n')
           line[strlen(line) - 1] = '\0';
       strcpy(lines[lineIndex], line);
       lineIndex++;
   }

   fclose(fp);

   // Create output file
   FILE *outputFile = fopen("output.txt", "w");
   if (outputFile == NULL)
   {
       perror("Error creating output file");
       // Free allocated lines
       for (int i = 0; i < MAX_LINES; i++)
       {
           free(lines[i]);
       }
       free(lines);
       return 1;
   }
   int i=1;
   int j=5;         //begin Permno number
   int k=10927;     //begin PRC date
   int m=21849;     //begin DLRETX data
   int count=0;

   int jj=10923;    // end PERNMO data
   int kk=21846;    // end PRC data
   int mm=32767;    // end DLRETX data
   int count_whileLoop=0;


   // Append lines
   for (i,j,k,m;  j<=jj,k<=kk,m<=mm;  i++,j++,k++,m++)
   {
       fprintf(outputFile, "%s%s%s\n", lines[j], lines[k], lines[m]);

   }

   // Free allocated memory
   for (int i = 0; i < MAX_LINES; i++)
   {
       free(lines[i]);
   }
   free(lines);

   // Close the output file
   fclose(outputFile);

   return 0;
}

推荐答案

您只处理文件的前32768行,因此不需要阅读更多内容.不过,您也说过:

该模式始终在第32767行之后重复

因此,我假设您真正想要的是处理32768行的批次.在任何一种情况下,这意味着您只需要一次存储那么多行的空间,而不是一次存储整个文件.这大约只有10MB,可以很容易地留在文件作用域变量中.

因此,更改代码以使用该大小的静态缓冲区,消除任何动态分配,然后一次循环读取32768行并处理它们.

所以:

  • j<=jj,k<=kk,m<=mm并不能达到你的预期.你可能想要j<=jj && k<=kk && m<=mm
  • 变量jjkkmm不是很具描述性.最好使用横断面起点/终点的名称.

通过以上更改,您现在拥有以下内容:

#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LENGTH 300      // maximum length of a line in the input file
#define MAX_BATCH 32768          // the number of lines in an input batch

#define PERMO_START 5
#define PRC_START 10927
#define DLRETX_START 21849

#define PERMO_END 10923
#define PRC_END 21846
#define DLRETX_END 32767

char lines[MAX_BATCH][MAX_LINE_LENGTH];

int main()
{
   // Open the input file
   FILE *fp = fopen("input.txt", "r");
   if (fp == NULL)
   {
       printf("Failed to open the file.\n");
       return 1;
   }

   // Create output file
   FILE *outputFile = fopen("output.txt", "w");
   if (outputFile == NULL)
   {
       perror("Error creating output file");
       return 1;
   }

   int done = 0;
   do {
       memset(lines, 0, sizeof lines);

       // Read lines from the file and store them in lines array
       int lineIndex = 0;
       char line[MAX_LINE_LENGTH];
       while ((lineIndex < MAX_BATCH) && (fgets(line, sizeof(line), fp) != NULL))
       {
           // Remove newline character from the end of the line
           if (line[strlen(line) - 1] == '\n')
               line[strlen(line) - 1] = '\0';
           strcpy(lines[lineIndex], line);
           lineIndex++;
       }

       done = lineIndex < MAX_BATCH;

       // Append lines
       for (int j=PERMO_START, k=PRC_START, m=DLRETX_START;
                j<=PERMO_END && k<=PRC_END && m<=DLRETX_END;
                j++,k++,m++)
       {
           fprintf(outputFile, "%s%s%s\n", lines[j], lines[k], lines[m]);
       }
   } while (!done);

   // Close the input and output file
   fclose(fp);
   fclose(outputFile);

   return 0;
}

C++相关问答推荐

C限制限定符是否可以通过指针传递?

为什么信号量为空= 0,而不是阻塞?

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

初始变量重置后,char[]的赋值将消失

在Apple Silicon上编译x86的Fortran/C程序

X64:并发写入布尔数组

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

S和查尔有什么不同[1]?

类型定义 struct 与简单的类型定义 struct

将数组插入数组

-Wnonnull-Compare警告不是具有误导性吗?

如果格式字符串的内存与printf的一个参数共享,会发生什么情况?

';malloc():损坏的顶部大小';分配超过20万整数后

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

WSASocket在哪里定义?

memcmp 是否保证按顺序比较字节?

使用共享变量同步多线程 C 中的函数

malloc:损坏的顶部大小无法找出问题

无法在 C 中打开文本文件,我想从中读取文本作为数据并将其写入数组

将字节/字符序列写入标准输出的最简单形式