2016-07-23 3 views
-3

저는 C 프로그래밍 언어의 초보자입니다. C 프로그래밍 언어의 null 문자 ('\0')에 대해 매우 혼란 스럽습니다.C의 문자 배열?

아래 프로그램에 따르면 한 줄의 허용 문자 길이는 10 (MAXLINE10으로 정의 됨)입니다. 길이가 9 인 Navindren과 같은 입력은 배열 색인 0 ~ 8을 차지합니다. 줄 문자가 도달 할 때마다 색인 9에 추가되고 i1만큼 증가합니다. i10이고 s[10]'\0', s[10] = '\0'으로 지정됩니다.

여기에 혼란이 있습니다. 배열은 인덱스 0 - 9의 할당 된 공간이기 때문에 어떻게 가능합니까? 나는 많은 온라인 자원을 언급하는 것을 시도했다 그러나 설명은 충분하지 않다.

주요 기능 :

#include<stdio.h> 
#define MAXLINE 10 

int getline(char line[], int maxline); 
void copy(char to[], char from[]); 

main() { 
    int len;    /*current line length*/ 
    int max;    /*maximum length seen so far*/ 
    char line[MAXLINE];  /*current input line*/ 
    char longest[MAXLINE]; /*longest line saved here*/ 

    max = 0; 
    while ((len = getline(line, MAXLINE)) > 0) { 
     printf("%d\n", len); 
     if (len > max) { 
      max = len; 
      copy(longest, line); 
     } 
    } 

    if (max > 0) /* there was a line */ { 
     printf("%s", longest); 
    } else { 
     printf("No Lines Detected\n"); 
    } 

    return 0; 
} 

의 getline 함수 :

int getline(char s[], int lim) { 
    int c; 
    int i; 

    for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; i++) { 
      s[i] = c; 
    } 

    if (c == '\n') { 
     s[i] = '\n'; 
     ++i; 
    } 

    s[i] = '\0'; 
    return i; 
} 

복사 기능 :

/*copy: copy `from` into `to`; assume to is big enough*/ 
void copy(char to[], char from[]) { 
    int i; 
    i = 0; 

    while ((to[i] = from[i]) != '\0') { 
     ++i; 
    } 
} 
+4

'lines [10]'인's [10]'은 범위를 벗어 났으므로 액세스 할 수 없으며 (읽지도 쓴 것도) 말아야합니다. 그것에 접근하면 * 정의되지 않은 동작 *이 호출됩니다. – MikeCAT

+0

C 컴파일러가 인덱스가 범위를 벗어 났는지 확인하는 코드를 생성하기가 너무 어렵 기 때문에 "어떻게 가능합니까?" * 정의되지 않은 동작 *이 호출 될 때 어떤 일이 발생할 수 있습니다. – MikeCAT

+0

즉, 오류가 표시되지 않습니다. – naveenath

답변

2

getline 기능이 정지하거나 i9 도달 할 때 또는 다음 바이트가 읽을 때 파일은 '\n'입니다. . 루프의 끝에서 두 조건을 모두 가질 수 없으므로 i9보다 작 으면 '\n'이 추가되므로 유효하지 않은 위치 s[10]은 절대로 저장되지 않습니다. > 사실 - (한 번 실행, 루프 초기화 문)

  • i = 0
  • i < 9 : 여기
    +---+---+---+---+---+---+---+---+---+---+ 
    | N | a | v | i | n | d | r | e | n |\n | 
    +---+---+---+---+---+---+---+---+---+---+ 
    

    getline()에 의해 실행되는 단계는 다음과 같습니다

    의 입력 파일을 가정 해 봅시다

    는 바이트를 포함
  • c = getchar() ->c은> 진정한
  • c != '\n' - -> 진정한
  • s[i] = c-
  • c != EOF>is[8]'n'을 수신 할 때까지 루프가 상기 단계를 반복하여 이제 1

인 ->s[0]'N'

  • i++ 수신 i9으로 증가됩니다.

    마지막 단계는 다음과 같습니다

    • i < 9 -> 거짓, 루프가 종료됩니다.
    • if (c == '\n') -> false, 'n'이 아닌 c'\n'이 아니라면 줄 바꿈이 읽혀지지 않았습니다. if 분기를 건너 뜁니다.
    • s[i] = '\n' ->s[9]은 null 바이트 인 '\0'을 수신합니다.
    • return i; -> 값 9이 호출자에게 반환됩니다.

    은 참으로 getline()의 구현에 문제가 있습니다 : 당신은 대상 배열의 크기에 대한 인수를 전달하지만, 코드 대신 하드 코딩 된 값 MAXLINE을 사용합니다.

    이 문제 외에도이 동작은 fgets()과 매우 유사합니다. 이 방법을 의도 했습니까? 아니면 쓸모없는 안전하지 않은 기능인 gets()처럼 줄 바꿈이없는 줄을 읽으려고 했습니까?

  • +0

    당신이 질문을 오해했다고 생각합니다. 예를 들어 입력이 "Navindren"문자열 일 때 어떤 일이 발생합니까?이 입력을 사용하여 코드를 디버그하고 관찰 한 내용을 명확하게 말해 줄 수 있습니까? – naveenath

    +0

    이 대답은 이미 힌트를 제공합니다. "코드 디버그"부분은 자신의 일입니다. – artm