2010-02-20 3 views
2

내가 파일에서 이름 배열을 채우기 위해 노력하고있어 여기에배열에 C로 문자열을 채우려면 어떻게해야합니까?

Andrew 
Andy 
Bob 
Dan 
Derek 
Joe 
Pete 
Richy 
Steve 
Tyler 

내가 쓴 기능입니다 ...하지만 프로그램이 충돌 나는 그것을 실행하면

#include <stdio.h> 

main(){ 
    int i=0, size=10; 
    char fname[15]; 
    char** data; 
    char* name; 
    FILE* fp; 

    printf("Enter a filename to read names:\n"); 
    scanf("%s", fname); 

    fp = fopen(fname, "r"); 
    if(fp == NULL) 
    exit(); 

    data = (char**)malloc(sizeof(char**)*size); 

    while(!feof(fp)){ 
    fscanf(fp, "%s", name); 
    data[i] = (char*)malloc(sizeof(name)); 
    data[i] = name; 
    i++; 
    } 

    fclose(fp); 

    printf("\n\n"); 

    for(i=0; i<size; i++) 
    printf("%s ", data[i]); 

    free(data); 
} 

누구나 알고 내가 뭘 잘못하고있어? 감사합니다.

답변

5

는 현재 오류의 몇 가지가 있습니다. 당신은 단순히 사용하여이 문제를 얻을 수 있습니다 : 당신이 fscanf를 사용할 때

다음
char name[128]; 

, 당신이 가진 것 :

fscanf(fp, "%127s", name); // stores this in name correctly, now... 

2) 부적절 data[i]을위한 공간을 할당하고 있습니다 :

data[i] = (char*)malloc(sizeof(name)); 

이렇게하면 문자가 (char*) 인 포인터를 보유 할 공간을 할당합니다. 이름은이므로. 수행해야 할 작업 :

data[i] = (char*)malloc(sizeof(char) * (strlen(name) + 1)); 

이렇게하면 데이터에 대해 하나의 종료 문자와 충분한 공간이 할당됩니다.

3) data[i]을 올바르게 할당하지 않았습니다. 당신은 여기 =를 사용하지만, strcpy를 사용할 필요가 없습니다

strcpy(data[i], name); 

4) 당신은 data[..] 요소의 개별 포인터를 자유롭게 아닙니다. 당신은 무료로, 당신의 printf 후, 추가해야합니다 :

for(i=0; i<size; i++) 
{ 
    printf("%s ", data[i]); 
    free(data[i]); // Free each pointer you allocate 
} 

모든 malloc 호출이 결국 일치 free 전화를해야한다.

+0

Reed, 나는 당신이 succintly하고 정확하게 대답했기 때문에 downvote하지 않을 것이다. 그러나 당신이 그를 프로세스에 대해 생각하게하지 않을 때 그를 도와주지 않을 것이다. –

+0

정말 고마워. 지금 일하고있어. 그리고 네, 이제 제가 잘못한 것을 이해합니다. – Andrew

+1

@San Jacinto : 잘 모르겠다. 나는 이것이 분명하다고 느꼈지만 코드를 다시 작성하지는 않았다. 왜 것들이 결함인지 지적하지 않고 도울 수는 없지만 ... 나는 당신의 요점을 보았습니다. @ Andrew : 그것이 작동하고있어 기쁩니다. 그리고 지금 당신은 그것을 이해하고 있습니다. –

5

이름 공간을 할당하지 마십시오.

fscanf(fp, "%s", name); 

변화가 너무 파일 이름 위해 imput을 제한해야

char name[100]; 

fscanf(fp, "%99s", name); 

: 또한

scanf("%14s", fname); 

당신은 그러나 당신은이 라인에 물건을 넣어 각 요소에 대한 데이터를 절대 사용하지 마십시오. 배열에서 큰 시스템의 서브 루틴이면 메모리 누수가 발생합니다. name가 저장받을 곳

1) 메모리를 할당하지 :

+0

아 ...하지만 얼마나 많은 공간을 알아야합니까? 이름이 얼마나 될지 모르겠다면 할당 해 주시겠습니까? 모든 줄마다 문자를 스캔해야합니까? – Andrew

+0

줄 길이 제한이 있어야합니다. 버퍼를 생성하고 스캔하면 나머지는 잘립니다. 끝없이 긴 라인을 원하면 모든 것을 읽을 때까지 버퍼를 동적으로 재 할당해야합니다. 그런 다음 이름에 바이트 수 (+1)를 정확히 할당하고 이름에 strncpy를 할당하십시오. – kibitzer

+0

나는 방금 정말로 큰 버퍼를 만들었다. 그러나 원한다면 먼저 스캔하여 카운트 할 수 있습니다. 숙제를하면 큰 버퍼를 만들 수 있습니다. IMHO – Hogan

0

많은 문제가 있습니다. 이름에 대한 다른 대답은 초기화되지 않기 때문에 반복하지 않을 것입니다.

두 번째 문제는 EOF를 올바르게 처리하지 못한다는 것입니다. feof는 일단 파일의 끝 부분을 읽으려고하면 true를 반환합니다. 그래서 당신은 빈 11 번째 이름을 얻을 것입니다.

마지막 문제는 데이터 배열에 10 개의 이름 만 저장할 수 있다는 것입니다. 두 번째 문제로 인해 빈 11 번째 이름으로 버퍼가 오버플로됩니다. 또한 코드는 입력 파일의 세부 사항에 달려 있습니다. 더 많은 이름을 가진 다른 입력 파일을 제공하고 문제 2를 해결 한 후에도 충돌이 발생합니다.

관련 문제