2011-11-29 3 views
3

전적으로 중국어 인 .txt 파일을 열려고합니다. 스트림이 100 % 유니 코드이거나 광범위한 문자를 처리하기위한 특별한 도구가 있더라도 일반 fopen/fclose 절차를 사용할 수 있습니까? 정답에 감사 드리며 초보 프로그래머입니다. 표준 gcc가있는 Linux를 사용하고 있습니다.순수 C로 유니 코드 파일 열기

내 코드를 첨부 하겠지만 오류없이 컴파일하지만 실행시 세그먼트 오류가 발생합니다. 나는 그것이 무엇이 잘못되었는지 모른다. 이 프로그램의 요점은 주어진 세트의 특정 기호가있는 중국어 기호의 각 문자열을 복사하고이를 별도의 파일에 쓰는 것입니다.

#include<stdio.h> 
#include<stdlib.h> 
#include<wchar.h> 
#include <locale.h> 
#define PLIK_IN in /*filenames*/ 
#define PLIK_OUT out 
#define LKON 49 /*specifying the length of a string on the left from a desired sign*/ 
#define PKON 50 /*...and on the right*/ 
int wczytaj_pliki(FILE*, FILE*); /*open file*/ 
void krocz_po_pliku(FILE*, FILE*); /*search through file*/ 
int slownik(wchar_t); /*compare signs*/ 
void zapisz_pliki(FILE*, FILE*); /*write to file*/ 

void main(void) 
{ 
    FILE *bin,*bout; 
    setlocale(LC_CTYPE, ""); 

    wczytaj_pliki(bin, bout); 
    krocz_po_pliku(bin, bout); 
    zapisz_pliki(bin, bout); 
}/*main*/ 

int slownik(wchar_t znak) /*compare characters*/ 
{ 
    wchar_t gznak1 = L'股', gznak2 = L'利', gznak3 = L'红'; 
    if ((znak == gznak1) || (znak == gznak2) || (znak == gznak3)) return 1; 
    return 0; 
}/*slownik*/ 

void krocz_po_pliku(FILE* bin, FILE* bout) /*search through file*/ 
{ 
    wchar_t wch; 
    wchar_t* kontekst; 
    int i = 0, j, step = LKON, counter = 0, token = 0; 

    while ((wch = getwchar()) != EOF) 
    { 
     if (!token) /*comparing consecutive signs*/ 
    { 
     if (slownik(wch) == 1) 
     { 
      counter++; 
      fprintf(bout,"###Wystapienie %d.\n\n", counter); 
      if (i<step) step = i; 
      fseek(bin,-step,1); 
      j=0, token = 1; 
     }/*if*/ 
     else i++; 
    }/*if*/ 
    else /*writing consecutive signs within context*/ 
    { 
     if (j < LKON + PKON) 
     { 
      putwc(wch, bout); 
      j++; 
     }/*if*/ 
     else 
     { 
      fprintf(bout,"###\n\n"); 
      fflush(bout); 
      token = 0; 
     }/*else*/ 
    }/*else*/ 
    }/*while*/ 
     printf("Znalazlem %d wystapien\n", counter); 
}/*krocz_po_pliku*/ 

int wczytaj_pliki(FILE* bin, FILE* bout) 
{ 
    bin=fopen("PLIK_IN","r"); 
    bout=fopen("PLIK_OUT","w"); 
    rewind(bin); 
    if(bin==NULL || bout==NULL) 
{ 
    printf("Blad plikow\n"); 
    exit(0); 
}/*if*/ 
    return 1; 
}/*wczytaj pliki*/ 

void zapisz_pliki(FILE* bin, FILE* bout) 
{ 
fclose(bin); 
fclose(bout); 
} 
+1

처음으로 중국어 문자 리터럴과 폴란드어 (?) 변수 이름의 조합을 처음 보았습니다. – dan04

+3

유니 코드 100 %? 집중도가 아닌가요? 85 %의 유니 코드 만 보이는 파일은 어떻겠습니까? –

답변

1

귀하의 문제는, 사실에 의해 발생할 수 있습니다 당신

#define PLIK_IN in /*filenames*/ 

다음

bin=fopen("PLIK_IN","r"); 

당신의 프로그램이 PLIK_IN라는 이름의 파일이 아닌 in라는 이름의 파일을 열려고된다. PLIK_IN이 없으면 fopenreturns0입니다. 0rewind으로 전달하면 실행 파일이 종료됩니다.

당신이 in을 열고 싶은 경우에, 당신은 같은

#define PLIK_IN "in" /*filenames*/ 
/* ... */ 
bin=fopen(PLIK_IN,"r"); 

PLIK_OUT 간다해야한다.

마지막으로 영어로 작성하는 것을 잊지 마십시오. lingua franca 우리 사업에있어 그것을 사용하면 당신을 도울 수있는 사람들의 숫자가 상당히 증가합니다 :)

2

예, fopen은 char *로 파일 이름을 나타낼 수있는 한 유니 코드 데이터를 포함한 모든 데이터가 포함 된 파일을 열 수 있습니다. (일부 플랫폼, 즉 Windows에서는 파일에 char *로 표시 할 수없는 이름이있을 수 있습니다).

대체가 행해지므로 (유니 코드 인코딩이 UTF-8이 아니고 상관 없습니다) 행 라인 교체를 방지하려면 이진 모드로 파일을 열려고합니다 의 문자. 또한 코드 단위가 1 바이트 이상인 경우 올바른 엔디안으로 읽어야합니다.

wchar_t는 반드시 유니 코드가 아니며 파일에서 사용되는 유니 코드 인코딩에 적합한 유형이 아닐 수 있습니다. 그리고 프로그램이 여러 유니 코드 인코딩을 지원하는 경우 파일을 사용하는 인코딩을 추측하기 위해 BOM을 사용하지 마십시오.

+0

짧은 이름을 사용하여 Windows에서 비 ANSI 이름을 가진 파일을 열 수 있습니다. – dan04

+0

짧은 이름을 항상 사용할 수있는 것은 아니며 나중에 Windows는 파일을 전혀 지원하지 않는 새로운 파일 시스템 (ReFS)으로 이동합니다. – bames53

관련 문제