【问题标题】:Reading huge Txt in C在 C 中读取巨大的文本
【发布时间】:2016-04-20 06:36:23
【问题描述】:

我想读取一个行数超过 5.5M 的文本文件,但是,对于测试建议,我只读取了一个 900 行和 70 列的文件并将其存储在 matrix x[1000][100] 中。

我这样做是因为我想识别包含日期的文本文件的第 13 列。此外,我会将这些文本拆分为许多其他包含每天数据的文本文件。

我将创建另一个具有相同值的文本文件,每次第 13 列更改时,我都会写一条消息说"NEW DAY"。之后,我会使用其他软件来追踪这个"NEW DAY",并在找到时进行拆分。

line 385 之前一切正常,记住每行大约有70 columns,但是,在这个值之后,我不知道为什么文件停止识别每行13th column 的变化,并且当数字改变时停止写"NEW DAY"

数据是这样显示的:

TAM 2000-03-07T16:55    22.78   5.50999 2   110 1   233 2.2 65  0.3 293 0

T 后面的数字是我要跟踪的那个。

代码如下:

int main()
{
    long int i = 0;
    long int j = 0;
    char x[1000][100];
    FILE *file = fopen("Entrada.txt", "r");
    FILE *file2 = fopen("Saida.txt", "w");

    while ((x[i][j] = fgetc(file)) != EOF) {
        if(i>=1 && j==70) {
            if(x[i][13] != x[i-1][13]) {
                for(j=0; j <= 70;j++) {
                    fprintf(file2, "%c", x[i-1][j]);
                    printf("%c", x[i-1][j]);
                    if(j==70){
                        fprintf(file2, "\n %s \n","New Line");
                        printf("\n %s \n","New Line");
                    }
                }
            } else {
                for(j=0; j <= 70 ;j++) {
                    fprintf(file2, "%c", x[i][j]);
                    printf("%c", x[i][j]);
                    if(j==70) {
                        fprintf(file2, "\n %s \n","");
                        printf("\n %s \n","");
                    }
                }
            }
        }

        if(x[i][j] =='\n'){
            i++;
            j=0;
        } else {
            j++;
        }
    }

    fclose(file2);
    return 0;
} 

【问题讨论】:

  • 是否有理由将所有行存储在一个数组中?什么时候不只是逐行处理文件?
  • 我不知道如何逐行存储。对我来说,我只需要将一行与之前的行进行比较,然后将这些内容写入另一个文本文件中。关于动态内存分配,好吧,很抱歉,但我不知道应该在哪里使用它。我的意思是,我应该用它来创建一个更大的矩阵?因为我可以读取整个矩阵,所以问题是它会停止验证列。
  • 忘记我的第一条评论(我刚刚删除了它)。您的程序非常复杂,只需使用fgets 逐行读取文件,并在读取时处理这些行。您不需要将所有内容存储在数组中。
  • 谢谢你,Michael,我现在就试试。真的谢谢你!

标签: c text vector


【解决方案1】:

您在问题中声明您需要检查第 13 个字符以查看日期是否更改,但您似乎只检查一天中的一位数字。天数可以有两位数。

在 C 数组中,索引基于 0,因此根据您的示例输入,它看起来像索引 应检查第 12 和 13 列,即第 13 和 14 列。

您不需要存储所有行并进行比较,只需存储变化的信息,即告诉您日期的两个字符。

你可以试试这样的:

char line[100];
char old12 = ' ';
char old13 = ' ';
long row = 0;
while (fgets(line, sizeof(line), file1) != NULL)
{
  if (row++>0)
  {
    if (line[12] != old12 || line[13] != old13)
    {
      /* remove \n */
      char* nl = strchr(line,'\n');
      if (nl) *nl = '\0';
      fprintf(file2,"%s", line );
      fprintf(file2, " New Line\n" );
    }
    else
    {
      fprintf(file2,line);
    }
  }
  else
  {
    fprintf(file2,line);
  }
  old12 = line[12];
  old13 = line[13];
}

如果您正在处理一个大文件,拥有一个大的二维数组肯定会给您带来问题,而是尽量在内存中保留尽可能少的文本。

您没有描述您的数据,但如果数据中存在空白,您可能需要检查整个日期而不是仅检查日期,否则将无法检测到这样的行:

TAM 2000-03-07T16:55    22.78   5.50999 2   110 1   233 2.2 65  0.3 293 0
TAM 2000-04-07T16:55    22.78   5.50999 2   110 1   233 2.2 65  0.3 293 0

【讨论】:

  • 感谢您的帮助,您也给了我一个想法。我只是检查了一天的最后一个数字,因为即使你有两位数,当日期改变时,最后一个数字总是与最后一天不同。即使它是 09 然后传递到 10,最后一位数字也会从 9 变为 0。关于数据,它们是很多行,就像我用作样本的那样,它们是 30.000 个文件,有 44640 行,固定 67 列。
【解决方案2】:

各位,我为我的问题找到了解决方案,它适用于超过 1700 万行的大型文件。

这是代码,它非常大,可能我做了很多不必要的事情,因为我不是 C 专家。

谢谢大家的帮助,这里是代码

#include <stdio.h>
#include <stdlib.h>

int TAM_BUFFER = 75; 
int TAM_BUFFER2 = 75; 
int count = 0;

int main(int argc, char *argv[])
{
FILE *arquivo = fopen("ConcatenatedFiles.txt", "r");
FILE *saida = fopen("Saida.txt", "w");

char buffer[TAM_BUFFER];
char buffer2[TAM_BUFFER2];

if(arquivo != NULL){

while(fgets(buffer, TAM_BUFFER, arquivo)){
    
        if(count==0){
            printf("%s\n", buffer);
         }
    
        count++;

        
        if(count>1){
            if(buffer2[13]!=buffer[13]){
                printf("%s\n", buffer2);
                printf("%s\n", "NEW DAY");
                printf("%s\n", buffer);
                
                fprintf(saida,"%s\n", buffer2);
                fprintf(saida,"%s\n", "NEW DAY");
            }
            else{
                if(buffer2[12]!=buffer[12]){
                printf("%s\n", buffer2);
                printf("%s\n", "NEW DAY");
                printf("%s\n", buffer);
                
                fprintf(saida,"%s\n", buffer2);
                fprintf(saida,"%s\n", "NEW DAY");
                }
                else{
                    printf("%s\n", buffer2);
                    printf("%s\n", buffer);
                
                    fprintf(saida,"%s\n", buffer2);
                    fprintf(saida,"%s\n", buffer);
                }
            }
        }
        
        if(count>=1){
        fgets(buffer2, TAM_BUFFER2, arquivo) ;

      }
      
        if(count=1){
            if(buffer[13]!=buffer2[13]){
                printf("%s\n", "NEW DAY");
                
                fprintf(saida,"%s\n", buffer);
                fprintf(saida,"%s\n", "NEW DAY");
            }
            else{
                if(buffer[12]!=buffer2[12]){
                printf("%s\n", "NEW DAY");
                
                fprintf(saida,"%s\n", buffer);
                fprintf(saida,"%s\n", "NEW DAY");
                }   
            }
          }
}
printf("%s\n", buffer2);

fclose(arquivo);
fclose(saida);
}
else
 printf("Not possible to open the file.");

printf("\n\n");
system("PAUSE");
return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2013-11-13
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多