2017-03-15 5 views
-2

대체로 scanf() 함수를 사용하는 데 많은 문제가 생긴 후에 전체 문자열을 읽는 대안을 찾기로 결정했습니다. 전체 문자열은 공백과 숫자 등이 섞인 단어를 의미합니다. \ n이 발견 될 때까지). 나는 stackoverflow에서 흥미로운 비트의 코드를 발견했다. 이 코드를 좀 더 다이나믹하게 변경 했으므로 키보드에서 char 입력 후에 memmory를 할당하려고했습니다. 내가 작동하지만, 오직 인수로 char **a와 함께있어, main()에서 나는 이것을 read(&w);이라고 부른다. 내 생각은 변수를 선언하지 않고도 사용할 수 있도록 인자없는 함수를 만드는 것이다. char *w 내가 문자열을 읽을 때마다. 여기에 내가 가진 코드의 : 사전대체 방법 scanf()

에서

char *read2() { 
int i = 0; 
char **a = NULL; 

while (1) { 

    *a = (char *)realloc(*a, (i + 1) * sizeof(char)) // Error here 
     scanf("%c", &(*(*a + i))); 
     if (*(*a + i) == '\n') { break; } 
     else { i++; } 
} 
    *(*a + i) = '\0'; 
return *a;} 

감사 : 이제

char *read(char **a) { 
int i = 0; 

while (1) { 
    *a = (char *)realloc(*a, (i + 1) * sizeof(char)); 
    scanf("%c", &(*(*a + i))); 

    if (*(*a+i) == '\n') 
     break; 
    else 
     i++; 
} 
*(*a+i) = '\0'; 
return *a;} 

내가 인수를 취하지이 기능을 수정하기 위해 노력하고있어하지만 쓰기를 얻고있다가/액세스 위반 읽기 오류

+0

정확히 무엇이 문제입니까? –

+0

POSIX에는 원하는 것을 수행하는'getline()'함수가 있습니다. 그것을 사용할 수 있습니까? – Barmar

+0

'fgets' 또는'getline'의 1000 번째 버전을 다시 발명하려고하십니까? ''read'라는 이름을 사용하는 것은 매우 나쁜 생각입니다. 왜냐하면 그것은 일반적으로 플랫폼 시스템 라이브러리에 의해 이미 정의되어 있기 때문입니다. – Olaf

답변

1

함수의 문제점은 너무 많은 수준의 간접 지정을 선언했기 때문입니다. 신고 함

char **a = NULL; 

다음으로 *a에 할당하십시오. 그러나 a == NULL부터이 포인터는 정의되지 않은 동작 인 null 포인터를 통해 간접적으로 발생합니다.

로컬 변수에 추가 수준의 간접 참조가 필요하지 않습니다. 매개 변수에만 필요하기 때문에 호출자의 변수를 업데이트 할 수 있습니다.

읽을 때 EOF도 확인해야합니다. scanf()을 사용하는 대신 getc()을 사용하십시오.

char *read2() { 
    int i = 0; 
    char *a = NULL; 

    while (1) { 
     a = (char *)realloc(a, (i + 1) * sizeof(char)); 
     int c = getc(stdin); 
     if (c == '\n' || c == EOF) { 
      break; 
     } else { 
      a[i] = c; 
      i++; 
     } 
    } 
    a[i] = '\0'; 
    return a; 
} 
+0

와우, 간접적 인 수준으로,이 사실을 알지 못해서 C의 완전한 초보자처럼 느껴지지만 감사합니다 @Barmar는 훌륭하게 작동했습니다. 다들 감사 해요 – Ferro

0

너는 진짜로 너의 것을 굴릴 필요가 없는다, 다만 fgets()을 사용 하십시요.

getline() 기능을 반드시 사용해야하는 경우 fgetc()으로 대신 입력하십시오.

+0

'fgets()'는 배열 전체를 길게 줄이지 않으면 배열을 재 할당하지 않습니다. – Barmar

+0

그렇기 때문에'getline()'을 제안합니다. –

-1

char ** - 이것은 단지 문자 포인터이므로 char *을 사용하십시오. 그런 다음 모든 곳에서 *을 제거 할 수 있습니다.

+0

이렇게하면 'realloc'으로 배열을 확장 할 수 없습니다. – Barmar

+0

왜 안 되니? 포인터를 건네면 포인터가 다시 할당됩니다. – bace1000

+0

'char **'는 "문자 포인터"가 아닙니다. 그리고 C는 가치에 의한 전달입니다. 그게 의미하는 바를 생각해보십시오. – Olaf