2014-09-29 2 views
2

지금 나는 학교에서 C 프로그램으로 일하고 있으며 파일에서 텍스트를 읽는 데 문제가 있습니다. 나는 Java로만 작업했기 때문에 아직 C에 익숙하지는 못하지만 꽤 간단하다고 확신 할 지 모르지만 철저하게 문제가 발생합니다. 나는 각 단어에 받아 보관해야파일에서 데이터 읽기, 영문자 만

boo22 $ Book5555bOoKiNg # BOO # TeX123tEXT (JOHN)를

을 : 여기

우리가 읽을 수있는 텍스트 파일에 서식 할 수있는 방법의 예 데이터 구조에서 단어는 알파 문자이므로 숫자 나 특수 문자는 없습니다. 이미 데이터 구조가 올바르게 작동하므로 각 단어를 char 배열로 가져와 내 구조에 추가해야합니다. 알파가 아닌 char 값이 될 때까지 각 문자를 계속 읽어야합니다. 나는 파일에서 스캔하는 여러 가지 방법을 조사해 보았고 내 시나리오에 가장 적합한 것이 있는지 잘 모르겠습니다. 그것이 내가 STR 단어인지 아닌지 확인해야 다음 문 경우 첫 번째 충돌하지 않는 경우

char str[MAX_WORD_SIZE]; 
char c; 
int index = 0; 

while (fscanf(dictionaryInputFile, "%c", c) != EOF) //while not at end of file 
{ 
    if (isalpha(c)) //if current character is a letter 
    { 
     tolower(c); //ignores case in word 
     str[index] = c; //add char to string 
     index++; 
    } 
    else if (str[0] != '\0') //If a word 
    { 
     str[index] = '\0'; //Make sure no left over characters in String 
     dictionaryRoot = insertNode(str, dictionaryRoot); //insert word to dictionary 
     index = 0; //reset index 
     str[index] = '\0'; //Set first character to null since word has been added 
    } 
} 

내 생각은, 그건되었다 : 여기

내가 내 입력을 지금 가지고있는 코드입니다 왜 str의 0 인덱스가 null인지 아닌지를 검사한다. 나는 내가 가지고있는 문장이 맞지 않을지라도 추측하고있다. 그러나 현재 데이터 구조에 추가 될 때 str을 null로 재설정하는 방법을 알 수 없다. 지금 이걸 실행할 때 txt 파일을 인수로 전달하면 분할 오류가 발생합니다.

저는 제대로 된 트랙인지 알고 싶지만이 데이터를 읽는 방법에 대한 도움이되지는 않을 것입니다.

처음으로 여기에 올리는 글입니다. 나에게 알려주지 않으면 더 많은 정보를 기쁜 마음으로 알려 드리겠습니다.

+0

1) 'fscanf (dictionaryInputFile "%의 C', c) '->'fscanf (dictionaryInputFile"%의 C ", 및 c) '루프가 추가되지 않고 종료 될 때 – BLUEPIXY

+0

2) 단어가 처리되고 . – BLUEPIXY

+0

제안'int c; while ((c = fgetc (dictionaryInputFile))! = EOF)'- (고맙습니다 @ BLUEPIXY). – chux

답변

2

가장 큰 문제 : fscanf()의 잘못된 사용. @BLUEPIXY

// while (fscanf(dictionaryInputFile, "%c", c) != EOF) 
while (fscanf(dictionaryInputFile, "%c", &c) != EOF) 

오버플로 방지 기능이 없습니다. '\0'도 아닌 알파 '\0'에 대한 테스트 때 확실한 이유

// str[index] = c; //add char to string 
if (index >= MAX_WORD_SIZE - 1) Handle_TooManySomehow(); 

하지 않습니다. 서명 char가 전달 될 때

Pedantically, isalpha()는 문제가있다. unsigned char 값을 is...((unsigned char) c))으로 전달하는 것이 좋습니다 (코드가 EOF이 아님). 또는 int ch = fgetc(stream)을 사용하여 입력을 저장하고 is...(ch))을 사용하십시오.

보조 : 배열 색인이 int 인 경우 size_t을 사용하는 것이 더 좋지만, size_t은 서명되지 않으므로주의해야합니다. size_t 배열은이 경우와는 달리 를가되어야 중요합니다.

또한 EOF이 수신되면 단어가 포함되어 있어도 str의 데이터는 무시됩니다. @BLUEPIXY. 대부분의 경우

는, 영업 이익은 바른 길에있다.


다음은 버퍼 오버 플로우를 설명하지 않은 샘플 테스트 방식입니다.

전체 버퍼를 테스트 한 후 필요하면 char을 읽습니다. 알파가 발견되지 않은 경우 길이가 0이 아닌 작업이 누적되면 사전에 추가하십시오.

char str[MAX_WORD_SIZE]; 
int ch; 
size_t index = 0; 

for (;;) { 
    if ((index >= sizeof str - 1) || 
     ((ch = fgetc(dictionaryInputFile)) == EOF) || 
     (!isalpha(ch))) { 
    if (index > 0) { 
     str[index] = '\0'; 
     dictionaryRoot = insertNode(str, dictionaryRoot); 
     index = 0; 
    } 
    if (ch == EOF) break; 
    } 
    else { 
    str[index++] = tolower(ch); 
    } 
} 
+0

도움 주셔서 감사합니다. 당신이 말한 모든 것이 의미가 있습니다. 특히 오버플로를 방지하는 데있어서, 그것이 내가 모르는 일 이었기 때문에. 내가 옳은 길 위에 대부분 있었다라는 것을 알고 있기 때문에 기쁜. –

+0

@BLUEPIXY 수정되었습니다. – chux

+0

제안 된 코드에 일치하지 않는 괄호로 인해 컴파일 오류가 있습니다. char 배열 'str []'에 넣기 전에 int 변수 'c'를 char으로 '줄여야'합니다. – user3629249