2017-12-21 5 views
-1

mytab2411.txt(サイズは15,017,210バイト)とshadow.txt(サイズは569バイト)の2つのファイルを比較したいのですが、このコードをコンパイルしてプログラムを実行すると、セグメンテーション違反。私は "mytab2411.txt"ファイルが "char buf"のサイズを超えていることを知っていますが、バッファをあふれさせることなくこの問題を解決するにはどうしたらいいですか?ファイルサイズがバッファサイズを超えています

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

int cmp(const void * s1, const void * s2) 
{ 
    return strcasecmp(*(char **)s1, *(char **)s2); 
} 

int cmp_half(const char * s1, const char * s2) 
{ 
    int i; 
    for (i = 0; i < 3; i++) 
    { 
     int res = strncasecmp((char *)s1+i*3, (char *)s2+i*3, 2); 
     if (res != 0) return res; 
    } 

    return 0; 
} 

char * line[1024]; 
int n = 0; 

int search(const char * s) 
{ 
    int first, last, middle; 
    first = 0; 
    last = n - 1; 
    middle = (first+last)/2; 

    while(first <= last) 
    { 
     int res = cmp_half(s, line[middle]); 
     if (res == 0) return middle; 
     if (res > 0) 
      first = middle + 1;  
     else 
      last = middle - 1; 

     middle = (first + last)/2; 
    } 
    return -1; 
} 

int main() 
{ 
    FILE * f1, * f2; 
    char * s; 
    char buf[1024*1024], text[1024]; 

    f1 = fopen("shadow.txt", "rt"); 
    f2 = fopen("mytab2411.txt", "rt"); 

    s = buf; 
    while (fgets(s, 1024, f2) != NULL) 
    { 
     line[n] = s; 
     s = s+strlen(s)+1; 
     n++; 
    } 

    qsort(line, n, sizeof(char *), cmp); 

    while (fgets(text, 1024, f1) != NULL) 
    { 
    text[strlen(text)-1] = 0; 
     int idx = search(text); 
     if (idx >= 0) 
     { 
      printf("%s matched %s\n", text, line[idx]); 
     } 
     else 
     { 
      printf("%s not matched\n", text); 
     } 
    } 

    return 0; 
} 
+2

チャンクで読み込みますか?メモリマップファイルですか?動的にメモリを割り当てますか?実際に行うことは、ユースケース、要件、および解決したい問題に依存します。 –

+0

このコードは '[C++]'のようには見えません。どのような解決策が欲しいですか?言語に応じて、それはかなり異なるでしょう。 – Lanting

+0

私の謝罪、私は間違ってC++にタグを付けました。私はCに基づいたソリューションが必要です。ダイナミックメモリの割り当てが好ましい –

答えて

1

この方法では、ファイルの各行が1024バイト長であることが前提です。実際には、行は最大1024バイトですが、ほとんどの行ははるかに短くなります。行の長さに基づいて各行にメモリを割り当てるには、strdupまたはmallocを使用します。

動的に割り当てられた配列に行を格納します。これは約15 MBのデータであり、リソースの制限がない限り問題にはなりません。

int main(void) 
{ 
    char buf[1024]; 
    char **arr1 = NULL; 
    char **arr2 = NULL; 
    int size1 = 0; 
    int size2 = 0; 
    FILE * f1, *f2; 
    f1 = fopen("shadow.txt", "r"); 
    f2 = fopen("mytab2411.txt", "r"); 

    while(fgets(buf, 1024, f1)) 
    { 
     size1++; 
     arr1 = realloc(arr1, sizeof(char*) * size1); 
     arr1[size1 - 1] = strdup(buf); 
    } 

    while(fgets(buf, 1024, f2)) 
    { 
     size2++; 
     arr2 = realloc(arr2, sizeof(char*) * size2); 
     arr2[size2 - 1] = strdup(buf); 
    } 

    for(int i = 0; i < size1; i++) 
     for(int j = 0; j < size2; j++) 
     { 
      if(strcmp(arr1[i], arr2[j]) == 0) 
       printf("match %s\n", arr1[i]); 
     } 

    return 0; 
} 
関連する問題