2013-08-16 76 views
1

我不明白函數getline在這裏是如何工作的。爲什麼換行符被排除在for循環之外,爲什麼在一個單獨的塊中測試換行符的存在?getline()函數在這裏如何工作?

#include <stdio.h> 
#define MAXLINE 1000 /* maximum input line length */ 

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

/* print the longest input line */ 
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) 
     if (len > max) { 
      max = len; 
      copy(longest, line); 
     } 
    if (max > 0) /* there was a line */ 
     printf("%s", longest); 
    return 0; 
} 


/* getline: read a line into s, return length */ 
int getline(char s[],int lim) 
{ 
    int c, i; 
    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) 
     s[i] = c; 
    if (c == '\n') { 
     s[i] = c; 
     ++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; 
} 

回答

1

getline將從stdin讀取一行。由於行由換行符('\n'個字符)分隔,所以getline將讀取幷包括換行符。 getline讀取換行符是沒有意義的,因爲它會讀取多行。

有三種情況可能導致for循環停止。

1) a \'n'遇到。
如果發生這種情況,它會在添加空終止符之前將換行符添加到當前字符串的末尾。這是if (c == '\n')的用途。

2) EOF被讀3)要讀取的字符的最大數量,被讀出。
如果發生這兩種情況,則會跳過將新行添加到字符串末尾並僅添加空終止符。

null終止符('\0'字符)是C如何表示字符串的結尾。

+0

得到it.that是非常簡單的。我看啊。 – chanzerre

0

閱讀時需要考慮三個重要情況,直到行尾。那些是:

  1. 我們已經達到了我們緩衝區允許的最大字節數。
  2. 我們已經達到了EOF,因此沒有別的可讀的。
  3. 我們已經達到了行尾字符,應該停止閱讀任何進一步的內容。

for循環,執行以下操作:

  • i < (lim - 1)檢查殼體1
  • (c = getchar()) != EOF檢查殼體2(難看)。
  • c != '\n'檢查情況3.

...它需要短路如讀換行符是因爲這是函數的強度的緣故。它也讀取換行符並將其包含在字符串中。最後一步:

s[ i ] = '\0'; 

...確保它是一個NULL結尾的字符串(C中的約定)。然後它返回讀取的字節數(這並不少見)。

1

之所以在循環中排除\ n並隨後檢查\ n是因爲在for循環完成後仍然會分配c的值(仍在範圍內)。他們似乎有點複雜的一個原因是他們決定排除方括號。由於函數是獲取下一行,當你得到換行符「\ n」時,一行會「結束」。要寫這個,所以它更可讀,它看起來像:

int getline(char s[],int lim) 
{ 
    int c, 
    int i; 
    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) { 
     s[i] = c; 
    } 
    if (c == '\n') { 
     s[i] = c; 
     ++i; 
    } 
    s[i] = '\0'; 
    return i; 
} 
1

那麼我也想出了這個問題。這是你的問題的可能答案。

1)在這個問題的第一個誤解是函數getline本身。 特別是在這段代碼中,getline是用戶定義的函數。 某些編譯器可能會彈出一個錯誤。因此,嘗試另一個名字這個功能(也許getl什麼你找到適合自己)

2)其次,main()中充當中間接受輸入字符串。 它檢查輸入字符串的長度(由函數getline()計算)是否大於零和最大值。

3)複製功能的副本的字符陣列中最長的最長字符串的值。

雖然打印代碼表示:輸出( 「%s」 時,最長的); 現在出現了一個問題。爲什麼不用for循環來打印字符串。 那麼這也是正確的,但它會需要更多的步驟和迭代效率低下。

這是我想出了。