2011-12-29 3 views
4

이 항목에 대한 K 및 R 책의 예제를 사용하려고 노력 중이지만 문제는 있습니다.C - 문자 배열 배열

'Father'배열의 각 요소가 문자 배열 (문자열)을 가리키는 Char 배열 배열이 필요합니다. 기본적으로 파일에서 한 번에 한 줄씩 배열에 저장하고 그 배열을 다른 배열에 저장하려고합니다. 그러면 qsort를 통해 정렬 할 수 있습니다.

하지만 이걸로 어디에도 갈 수없는 것 같습니다! 내 코드의 Anyhelp는 매우 만족합니다. 즉, 내가있는 곳에서 어디로 가야합니까?

EDIT : 문제는 인쇄 기능이 배열 배열 내에 있어야하는 내 단어를 인쇄하지 않고 대신 단지 인쇄 쓰레기입니다. 주된 문제는, 올바르게 배열의 배열에 추가할지 여부를 올바르게 참조하거나 전혀 참조하지 않습니다.

감사합니다.

#define MAXLINES 5000 /* max no. lines to be stored */ 
#define MAXLEN 1000 /* max length of single line */ 

char *lineptr[MAXLINES]; 

void writelines(char *lineptr[], int nlines); 

int main(int argc, char *argv[]) { 
int nlines = 0, i, j, k; 
char line[MAXLEN]; 
FILE *fpIn; 
fpIn = fopen(argv[1], "rb"); 
while((fgets(line, 65, fpIn)) != NULL) { 
    j = strlen(line); 
    if (j > 0 && (line[j-1] == '\n')) { 
     line[j-1] = '\0'; 
    } 
    if (j > 8) { 
     lineptr[nlines++] = line; 
    } 
} 
for(i = 0; i < nlines; i++) 
    printf("%s\n", lineptr[i]); 
return 0;  
} 
+0

일부 코드를 게시했지만 문제가 무엇인지 알려주지 않았습니다. 컴파일러 오류 메시지? 런타임 크래시? 잘못된 결과? 다른 것? –

+0

편집 됨, 사과. – PnP

+1

다음 단계는 문제를 단순화하는 것입니다. 더 간단한 프로그램을 작성하여 파일 읽기가 올바른지 확인하십시오. 그런 다음 정렬을 수행하는 별도의 간단한 프로그램을 작성하십시오. 일단 작업 한 사람이 있다면, 그들을 통합하십시오. –

답변

4

Dan definitely found one error, the identical storage. 하지만 여기에 더 많은 버그가 있다고 생각합니다 :

while((fgets(line, 65, fpIn)) != NULL) { 

65 만 남았습니까? 함께 작업 할 공간이 MAXLEN이라면 입력 내용을 조금 더 길게 만들 수 있습니다.

j = strlen(line); 
    if (j > 0 && (line[j-1] == '\n')) { 
     line[j-1] = '\0'; 
    } 
    if (j > 8) { 
     lineptr[nlines++] = line; 
    } 
} 

왜 정확히 j > 8입니까? 짧은 줄을 버리고 있습니까? 은 Dan이 제안한 동적 할당으로 이동 한 후이 경우 줄 바꿈을 해제하고 줄을 할당 취소해야합니다.

업데이트

ott recommends strdup(3) -이 기존 시스템에 맞게 쉬운 것입니다 :

line = calloc(MAXLINE, sizeof char); 
while((fgets(line, 65, fpIn)) != NULL) { 
    j = strlen(line); 
    if (j > 0 && (line[j-1] == '\n')) { 
     line[j-1] = '\0'; 
    } 
    if (j > 8) { 
     lineptr[nlines++] = line; 
    line = calloc(MAXLINE, sizeof char); 
    } 
} 
:

while((fgets(line, 65, fpIn)) != NULL) { 
    j = strlen(line); 
    if (j > 0 && (line[j-1] == '\n')) { 
     line[j-1] = '\0'; 
    } 
    if (j > 8) { 
     lineptr[nlines++] = strdup(line); 
    } 
} 

댄이 calloc(3)을 추천, 그 약간 더 많은 작업이 될 것입니다

물론, 메모리 할당이 실패 할 경우이 두 가지 방법 모두 폭발합니다. 메모리 할당에서 오류를 반환하는 것은 항상 좋은 생각입니다. 그리고 두 번째 메커니즘에 대해 굉장히 아름다운 것이 있습니다.

+0

WPA 단어로 작업하므로 8 자에서 63 자 사이로 입력하십시오 :) – PnP

+0

정직한 사람이라면 어디에서 시작 해야할지 확실하지 않습니다. ( – PnP

+0

대단히 감사합니다. Sarnold! – PnP

5

문제가 line[MAXLEN]는 자동 변수이기 때문에 while 루프를 통한 각각의 시간이 동일한 어레이를 지칭한다는 것이다. while 루프 (line = calloc(MAXLEN, sizeof(char))fgets에 전화하기 전에)를 통해 매번 line을 동적으로 할당해야합니다. 그렇지 않으면 fgets은 항상 동일한 메모리 위치에 쓰고 lineptr은 항상 같은 배열을 가리 킵니다.

+0

그 라인 메모리는 내가 라인을 읽을 때마다 할당 될 필요가있다. 그래서 나는 어떤 종류의 루프에서도 그것을 필요로 할까? – PnP

+0

예. 그것은 while 루프의 첫 번째 것이되어야합니다. 그런 다음 fgets를 사용하고 NULL을 확인한 후 – Dan

+0

calloc을 MAXLEN 과도 함으로 해결하십시오. 'lineptr [nlines ++] = strdup (line);'이면 충분합니다. –