2017-04-24 1 views
0

내 프로그램에 어떤 문제가 있는지 명확하지 않습니다. 파일을 열어 첫 번째 줄을 읽은 다음 인쇄하는 간단한 코드입니다. 그러나 프로그램은 계속 충돌합니다. 내 텍스트 파일의 실제 내용은 다음과 같습니다. 내 코드를 테스트하십시오.char * 문자열을 인쇄 할 수 없습니다.

int main(void) 
{ 
FILE *stream; 
char *s; 
stream = fopen("input.txt", "r"); 
fscanf(stream, " %s", &s); 

printf("%s", s); 


fclose(stream); 
return 0; 
} 

가 나는 <string.h>

+3

1.'fopen' 결과를 확인하지 않습니다. 2.'s'는 초기화되지 않은 포인터입니다. 데이터는 어디로 이동합니까? – John3136

+1

'char s [16]; fscanf (stream, "% s", &s);' – BLUEPIXY

+1

GCC를 사용한다면, 항상'gcc -Wall -Werror'로 컴파일하십시오. –

답변

3

s에있는 라이브러리 함수를 사용하지 않도록 지시하고있어 초기화되지 않은 포인터이다. 쓰기 위해서 fscanf을 위해 약간의 메모리를 할당해야합니다.

+0

char * s = NULL로 초기화했지만 프로그램이 계속 충돌합니다 – user43783

+0

() 쓸데없는 메모리를 제공하지 않는다. – aschepler

+0

스택 상에 메모리를 사용할 수있다. ('char s [10]'은 스택에 10 문자를 할당한다.) malloc을 사용하여 동적 메모리 할당을 사용한다 – d3L

0

코드에 누락 된 사항은 거의 없습니다.

// Uninitialise pointer, you need to allocate memory dynamically with malloc before you use it. That is 
char *s; 
int size = 20; // size of the string you want 
s = malloc(size * sizeof(char)); 

// Or you can use a VLA and with this you don't have to use free(s) 

char s[20]; 


// fopen could fail, always check the return value before using it. 
stream = fopen("input.txt", "r"); 

if(stream == NULL){ 
    perror("File opening failed"); 
     return EXIT_FAILURE; 
} 
fscanf(stream, "%s", s); 


//Don't forget to do free(s) to free memory allocated with malloc . when you are done with it 
0
char *s; 

(대부분의 시스템에서 32/64 비트) 메모리 어드레스를 유지하기 위해 필요한 바이트의 수를 할당. 그러나 포인터를 초기화하지 않으므로 포인터의 값 (주소는)은 정의되지 않습니다.

Ergo : fscanf가 정의되지 않은 메모리 주소에 쓰려고합니다.

char * s = NULL로 초기화했습니다.

예, 이제 포인터가 초기화되었지만 이제 아무데도 가리키고 있습니다.

Ergo : fscanf는 아무 것도 쓰지 않으려 고 시도합니다.

해결책은 fscanf가 사용할 수있는 메모리를 할당하는 것입니다. fscanf가 마법을 사용하여 메모리를 할당하지 않습니다!

스택 메모리 또는 동적 할당 메모리 (힙)를 사용할 수 있습니다.

스택 메모리는 관리하기가 쉽지만 힙보다 훨씬 작습니다. 여기

스택에 메모리를 사용하는 솔루션 : 내가 대신 %s%9s을 사용하는 이유 당신은

// Allocates 10 bytes on the stack 
// Given 1 Character = 1 Byte the 
// buffer can hold up to 9 characters. 
char myBuffer[10]; 

// Initialize s with the address of myBuffer 
char *s = myBuffer; 

// Call fscanf 
fscanf(stream, "%9s", s); 

궁금 할 수있다.

이유는 버퍼 오버 플로우 방지하는 것입니다

fscanf 버퍼가 얼마나 큰지 알고하지 않습니다, 그래서 당신은 그것을 알 필요가있다.

그렇지 않으면 fscanf는 할당 된 메모리 이외의 데이터를 씁니다.

일반적으로 C 문자열 및 메모리 관리에 대해 읽어 보시기 바랍니다.

+1

fscanf (stream, '% s'은 공백을 저장하지 않습니다''1 2 3 "과 같은 줄은''''로''s ''로 읽히지 않습니다. 2 3 "' – chux

+0

@chux 깔끔한 관찰. 그걸 몰랐어 :) – d3L

관련 문제