2014-11-23 63 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▯▯▯▯▯ 

我得到的

abcdefg 
1234 

預期輸出但是如果我輸入的是一樣的東西

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

xyz▯▯▯▯▯▯ 
987▯▯▯▯▯ 

我得到的輸出爲

abcdefg 
1234 

但我希望的

abcdefg 
1234 
xyz 
987 

好像我while語句的輸出,while ((better_line_length(s, MAXLINE)) > 0)main()停止當它遇到一個空行,而不是僅僅跳過它執行。我花了幾個小時,我仍然無法弄清楚爲什麼。我認爲設置better_line_length返回0如果一行的第一個字符是'\n'將修復代碼,但它不會改變一件事。

爲什麼我遇到這個意外的輸出,爲什麼上面的想法不能修復我的程序?

請記住K & R直到第1章前才引入某些高級主題,所以指針和某些其他主題對我來說還沒有意義。

謝謝!

回答

2

我看到你仍然在試圖解決這個問題。對你有好處,不要放棄!

至於你目前的解決方案的問題:你可以做的一件事是你可以修改better_line_length()函數返回的意思是有一個空行,並跳過while ((len = better_line_length(s, MAXLINE)) > 0)循環內的行。

例如,您可以添加以下的better_line_length()身體內部,for循環之後:

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

然後你會知道這是你需要跳過就行了。您還可以添加類似的返回碼,這意味着文件結尾處爲stdin

讓我知道你是否需要任何幫助。

+0

謝謝!我終於可以在你的幫助下工作,但我不太清楚爲什麼。 我在'for'循環後添加了你的建議,並且還添加了條件語句if(len> 0){'在我的while((len = better_line_length(s,MAXLINE)))'下,程序工作! 但我不明白爲什麼返回-1工作,但返回0不。由於循環只在'better_line_length()'大於0時才執行條件,所以當函數返回0或-1時不應該跳過行嗎? – jhschwartz 2014-11-24 01:43:47

+0

我覺得你還沒有完全理解while循環。它執行直到條件成立。它只會通過結束循環而不是處理更多行來「跳過」行。 – Persixty 2014-11-24 06:53:20

+0

你可能會感到困惑的是C處理方式/如果條件:整數可以像布爾值一樣處理:0(零)總是爲假,而非零(1,-1等)總是爲真。 – syntagma 2014-11-24 09:53:03

1

仔細查看該行你提到:

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

如果函數better_line_length()返回0的條件爲假,循環結束。 這就是爲什麼它放棄在第一個空白行。

當你真的到了最後或者只是一個空白行時,你應該考慮返回不同的東西。

您可能(例如)在到達輸入末尾時返回-1。

+0

但即使我將該行更改爲'while(better_line_length(s,MAXLINE)){'我仍然得到相同的輸出。 – jhschwartz 2014-11-23 22:30:33

+0

是的,因爲0是'假',所以你沒有真正改變任何東西! 如果您閱讀EOF並且行長度爲空,我仍然建議返回-1。然後你使用while((better_line_length(s,MAXLINE))!= - 1){ – Persixty 2014-11-23 22:34:31