2017-12-26 52 views
-3

나는 모든 길이의 사용자로부터 문자열을 받아들이고 그것을 표시하는 간단한 코드를 작성 중이다. 그러나 문자열을 받아들이지 만 제대로 인쇄하지 못하기 때문에 코드가 제대로 작동하지 않습니다.이 코드에 어떤 문제가 있는지 잘 모르겠습니까?

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
main() 
{ 
    int i,len; 
    static int n=5; 
    char a[20]; 
    char **s; 
    s=malloc(5*sizeof(char)); 
    char *p; 
    for(i=0;i<n;i++) 
    { 
     scanf("%s",a); 
     if(*a=='1')     /*to exit from loop*/ 
     { 
      break; 
     } 
     len=strlen(a); 
     p=malloc((len+1)*sizeof(char)); 
     strcpy(p,a); 
     s[i]=p; 
     if(i==n-1) 
     { 
      s=realloc(s,(5+i*5)*sizeof(char)); 
      n=5+i; 
     } 
    } 
    for(i=0;i<n-1;i++) 
    { 
     printf("%s ",s[i]); 
    } 
    free(p); 
    p=NULL; 
    return 0; 
} 
+0

'나는 길이에 상관없이 사용자의 문자열을 받아들이고 표시하는 간단한 코드를 작성하고 있습니다. ... 많은 일을하고 있습니다. 여기에서 일하고 있습니다 ... –

+0

* "나는 무엇이 일어나고 있는지 모르겠습니다. 이 코드가 잘못 되었습니까? "* - 단순한 물음표는 그 문장을 질문으로 만들지 않습니다. [이 게시물에 대한 디버깅] (https : // ericlippert.com/2014/03/05/how-to-debug-small-programs /). – StoryTeller

+1

당신은'길이의 사용자로부터 문자열을 받아 들일 수 있습니다. '하지만 당신은 단지 19 문자의 배열을 가지고 있습니다. –

답변

4

여러 문제가 있지만 첫번째보기에, 가장 눈에 띄는 사람은

s=malloc(5*sizeof(char)); 

잘못이다. schar ** 유형이므로 char *의 메모리를 할당해야합니다. 즉, schar * 요소를 가리킬 것으로 예상되므로 그에 따라 메모리를 할당해야합니다. 에게 실수이 종류를 방지하기 위해

이 아니라, 형태 OID 크기가 기본적으로 변수의 유형 결정,

s = malloc(5 * sizeof *s); // same as s=malloc(5 * sizeof (*s)) 

를 사용 하드 코딩 데이터 유형에 의존하지 않습니다. 두 가지 이점

  • 위와 같은 실수는 피하십시오.
  • 코드는 탄력이되고, 당신은 돈, t는 경우에 malloc() 문을 변경해야 당신이 말한

, scanf("%s",a); 또한 잠재적으로 위험한 데이터 유형을 변경하여 버퍼 오버 플로우를 일으킬 선택할 이상보다 -expected-input. 당신은 항상 당신이 모르는 또는의 길이를 지시하지 않는 경우, 논리에 대한 조언을했다

scanf("%19s",a); // a is array of dimension 20, one for terminating null 

처럼, 최대 필드 폭을 사용하여 입력 스캔 길이를 제한한다 입력 문자열을 미리 입력하면 문자열에 입력 입력으로 사용할 수 없습니다. 이 작업을 수행하기의 기본 방법은

  1. malloc()처럼 할당 기능을 사용하여 동적으로, 적당한 길이의 버퍼를 할당 할 것이다.
  2. 입력 스트림을 하나씩 계속 읽습니다 (fgetc() 또는 유사).
  3. 읽기가 완료되면 (예 : EOF의 리턴) 전체 입력을 읽은 것입니다. 할당 된 메모리가 소진되면
  4. free() 메모리를 잊지 마세요, 원래의 버퍼를 재 할당하고 3

단계를 계속합니다.

그렇지 않은 경우 fgets()을 사용하여 메모리 덩어리를 읽고 위에 언급 한대로 리알을 계속할 수 있습니다.