2013-11-24 70 views
0

我編譯下面的程序:從交流程序獲得輸出

#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; 
} 

我試圖在bash shell中運行它:

gcc -o longest-line longest-line.c 
./longest-line 

,基本上它變成一個正在運行的進程(顯示在結果ps aux)並且光標只是閃爍。在代碼中,當程序運行並調用getline函數時,它會執行1000次迭代,並且每次從終端獲取輸入以調用getchar,以便在計數器不是文件結尾或換行符時增加計數器。但是,立即在終端沒有輸入,並且當我開始添加輸入並按回車鍵時:

$ ./longest-line 
Hello World 
Hello Again 

沒有任何反應。它應該打印最長的行。

+0

你應該總是使用'{}'用的LOP,if語句等避免了大量的bug,並使其更容易爲他人(或自己幾個星期後, )讓你知道代碼是否是故意的或錯誤的。 – hyde

+0

@hyde本例來自「C語言程序設計語言(第2版)」一書。我直接複製它。但編譯好的時候,我不知道如何讓它在編譯後給它輸入時返回最長的行。 – JohnMerlino

+0

另外,使函數實現聲明,也就是將兩個函數移到文件的頂部並刪除前向聲明。這樣可以避免您獲取鏈接器錯誤並減少所需的維護(即更改函數簽名只需要在一個位置更改代碼)。 – Skizz

回答

0

因此,在我的編譯器中,我不得不解決一些小問題。

  • 一般來說,主要應寫爲int main() { ... }int main(int argc, char **argv) { ... }
  • getline()與從#include <stdio.h>拉入的內建函數衝突,因此我只是將您的名稱重命名爲getline_custom,並且也重命名了所有使用點。

話雖這麼說,這些小的修改,(這可能不是你的編譯器下需要),你的程序工作正常

我相信你的困惑是,直到你發送EOF之後,程序纔會打印最長的一行。在bash中,您可以使用CTRL + D

實施例:

[12:39pm][[email protected] /tmp] ./foo 
test   // Then I hit enter 
longest line // Then I hit enter 
short line // Then I hit enter 
one more  // Then I hit ctrl-D 
longest line // This is output from the program. 

又如:

如果我們使用重定向,我們可以更容易看到的輸入和輸出之間的差。

[12:42pm][[email protected] /tmp] printf "longest line\nshort line" | ./foo 
longest line 

,或者使用輸入文件:

[12:53pm][[email protected] /tmp] cat input.txt 
longest line 
short line 
foo 
blah 
[12:53pm][[email protected] /tmp] cat input.txt | ./foo 
longest line 

在另一方面

如果,另一方面,你想程序後打印當前最長的行每個行的輸入,那麼我們需要改變這個程序中的代碼。

這裏有一個例子:

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

    while ((len = getline(line, MAXLINE)) > 0) { 
     if (len > max) { 
      max = len; 
      copy(longest, line); 
     } 

     printf("Current longest line: %s", longest); 
    } 
} 
+0

是的,這正是我所尋找的 – JohnMerlino

+0

順便說一句,我不得不重新命名getline函數,但不必將int放在main的前面。 – JohnMerlino

+0

@JohnMerlino:這是一個合理的stackoverflow後關於想要主返回類型:http://stackoverflow.com/questions/2892787/why-would-you-precede-the-main-function-in-c-with- a-data-type請注意,C89表示1989年發佈的C標準,C99表示1999年發佈的C標準,C11表示2011年發佈的C標準。 –

1

的問題是,如果你從鍵盤按「\ n」 getline總是返回1,因爲這種說法

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

和線while ((len = getline(line, MAXLINE)) > 0)永遠是正確的。

但是,如果您使用一個文件作爲標準輸入,它會正常工作,因爲EOF。

如果您希望通過鍵盤輸入工作,請按Ctrl-D或Ctrl-Z來模擬EOF。

+0

如何在「C語言編程」一書中沒有方括號?我直接從書中複製這個。 – JohnMerlino

+0

是的,但如果在循環之外,則保留第二個 – 2013-11-24 18:08:09

+0

方括號表示'[]'...'{}'是(花括號)括號。 – hyde