2014-11-23 1 views
2

오히려 프로그래밍에 익숙하지 않으므로 나와 함께하시기 바랍니다.K & R 연습 문제 1-18 (C 프로그래밍 언어)에 대한 예기치 않은 결과

연습 1-18에 대한 프롬프트가 있습니다. 각 입력 행에서 후미 공백과 탭을 제거하고 완전히 빈 줄을 삭제하는 프로그램 작성.

그리고 여기 내 코드입니다 :

내 프로그램이 내게 기대하는 출력을 제공하지 않습니다
#include <stdio.h> 

#define MAXLINE 1000 

int better_line_length(char line[], int lim); 
void copy(char to[], char from[]); 

int main(void) 
{ 
    int len, a; 
    char s[MAXLINE]; 
    char better_s[MAXLINE]; 

    while ((better_line_length(s, MAXLINE)) > 0) { 
      copy(better_s, s); 
      printf("%s\n", better_s); 
     } 

    return 0; 
} 

int better_line_length(char s[], int lim) 
{ 
    int c, i, last_letter = 0; 

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

    s[last_letter] = '\0'; 

    return last_letter; 
} 

void copy(char to[], char from[]) 
{ 
    int i = 0; 

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

. 빈 줄이 없으면 뒤 공백과 탭을 제대로 제거하지만 공백 줄이 있으면 이상하게 보입니다. 내 입력되면

예를 들어, 내 입력

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯ 
1234▯▯▯▯▯ 

xyz▯▯▯▯▯▯ 
987▯▯▯▯▯ 
같은 경우

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯ 
1234▯▯▯▯▯ 

내가

abcdefg 
1234 

의 예상 출력을 얻을하지만 (▯▯▯에 공백이있는 곳)

출력이

0이됩니다. 1,233,657,

는하지만

abcdefg 
1234 
xyz 
987 

그것은 내 while 문처럼 보인다의 출력, 그냥 그 위에 건너 뛰는 대신 빈 줄을 발생할 때 실행 while ((better_line_length(s, MAXLINE)) > 0)main()에서 중지를 기대합니다. 나는 이것에 시간을 보냈다. 그리고 나는 아직도 이유를 이해할 수 없다. 나는 라인의 첫 번째 문자가 '\n' 인 경우 0을 반환하도록 better_line_length을 설정했지만 코드를 수정한다고 생각했지만 실제로는 변경되지 않습니다.

왜 이런 예기치 않은 결과가 발생하며 위의 아이디어로 내 프로그램이 수정되지 않는 이유는 무엇입니까?

K & R은 지난 1 장까지는 특정 고급 항목을 소개하지 않으므로 포인터와 특정 주제가 아직 이해가되지 않습니다.

감사합니다.

답변

2

나는이 운동을 해결하려고 여전히 노력하고 있음을 압니다. 너를 위해 좋은, 포기하지 말라!

현재 해결책의 문제점 : 한 가지 방법은 better_line_length() 함수를 수정하여 빈 줄이 있다는 의미를 반환하고 while ((len = better_line_length(s, MAXLINE)) > 0) 루프 내에서 해당 줄을 건너 뛰는 것입니다.

예를 들어, 당신은 바로 for 루프 후, better_line_length()의 몸 안에 다음을 추가 할 수 있습니다

if(i == 0 && c == '\n') 
    return -1; 

그런 다음 당신이 당신이 건너 뛸 필요가있는 라인이 있음을 알게 될 것이다. stdin의 파일 끝/끝을 의미하는 유사한 리턴 코드를 추가 할 수도 있습니다.

도움이 더 필요하면 알려주세요.

+0

고마워! 나는 마침내 당신의 도움으로 일할 수있게되었지만, 나는 왜 그런지 잘 모르겠습니다. 'for' 루프 다음에 제안에 추가했고, while ((len = better_line_length (s, MAXLINE)))') 및'while'에'if (len> 0)'의 조건문을 추가했습니다. 프로그램 작동! 하지만 왜 -1 반환하지만 0 반환 않는 이해하지 않습니다. 루프가'better_line_length()'가 0보다 큰 경우에만 조건문을 실행하기 때문에 함수가 0 또는 -1을 반환 할 때 라인을 건너 뛰지 않아야합니까? – jhschwartz

+0

나는 while 루프를 꽤 이해하지 못했다고 생각한다. 조건이 true가 될 때까지 실행됩니다. 루프를 끝내고 더 이상의 회선을 처리하지 않으면 선을 '건너 뜁니다'. – Persixty

+0

혼란 스러울 수있는 것은 C가 처리하는 동안의 처리 방법입니다. 조건 : 정수는 부울과 같이 처리 할 수 ​​있습니다. 0 (영)은 항상 거짓이고 0이 아닌 (1, -1 등)은 항상 참입니다. – syntagma

1

봐 밀접하게 줄에서 당신은 언급 : 조건이 false 루프가 종료

while ((better_line_length(s, MAXLINE)) > 0) { 

0 반환 better_line_length() 기능을합니다. 그래서 첫 번째 빈 줄을 포기합니다.

끝까지 다가 갔거나 공백 라인 만 반환하면 다른 것을 돌려 주어야한다고 생각해야합니다.

입력이 끝나면 -1을 반환 할 수 있습니다.

+0

그러나 그 행을 'while (better_line_length (s, MAXLINE)) {'로 변경하더라도 {나는 여전히 같은 출력을 얻습니다. – jhschwartz

+0

예, 0은 '거짓'이므로 실제 아무것도 변경하지 않았습니다! EOF를 읽고 줄 길이가 비어 있으면 -1을 반환하는 것이 좋습니다. 그럼 while ((better_line_length (s, MAXLINE))! = - 1) { – Persixty