1. 程式人生 > >庫檔案中getline函式的宣告已經存在

庫檔案中getline函式的宣告已經存在

 

/usr/include/stdio.h:651: note: previous declaration of ‘getline’ was here
#include<stdio.h>
#define MAXLINE 1000  /*maxinum input line size*/

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

/*print longest input line*/
main()
{
   int len;
   int max;
   char line[MAXLINE];
   char longest[MAXLINE];

   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 a big enough memory*/
void copy(char to[], char from[])
{
   int i;

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


"maxline.c" 52 lines, 911 characters

在linux下編譯出錯,錯誤為/usr/include/stdio.h:651: note: previous declaration of ‘getline’ was here

解決方案:

第一種我把程式中的getline給遮蔽掉,重新編譯,能通過,但是我實際執行的時候出現了segmentation fault的錯誤,發現其實這兩個getline的引數是不一樣的。所以使用庫檔案中的getline是不行的。

第二種是註釋掉stdio.h中的getline宣告,編譯和執行都沒有錯誤。

第三種是修改程式中的getline函式宣告,然後在使用getline的地方修改。

總結:第一種是不行的,第二和三種是可行的,但是第二種修改了庫檔案,所以不是很好。

以上是baidu出來的解決方法,看了總結,用第三種方法,把getline改成了getlines,編譯執行成功。

這個小程式裡面也涉及了很多sticky design problem。

1、如果遇到的輸入行比limit還大怎麼辦?(getline在陣列full時,不再收集lines。)

2、getline沒法提前知道輸入行會有多大,所以getline需要檢查overflow。

3、copy可以知道字串有多大,因此不需要新增錯誤檢查。

specialized  version

#include<stdio.h>


#define MAXLINE 1000


int max;
char line[MAXLINE];
char longest[MAXLINE];


int getlines(void);
void copy(void);


/*print longest input line;specilialized version*/
main()
{
   int len;
   extern  int max;    
/* state type and allocate the memory storage ,   external variable 和local variable的宣告一樣,但是因為它們一般是在函式外宣告,所以加external*/
   extern  char  longest[];


   max = 0;
   while((len = getlines()) > 0)
     if (len > max)
    {
           max  = len;

            copy();
      }
   if(max > 0)/*there was a line*/
       printf("%s", longest);
   return 0;
}


/*getline: specialized version*/
int getlines(void)
{
   int c,i;


   extern char line[];


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


/*copy : specialized version*/
void copy(void)
{
     int i;
     extern char line[], longest[];


     i = 0;
     while((longest[i] = line [i] )!= '\0')
        ++ i;
}


definition是指變數被建立(created),且分配了記憶體;

declaration是指變數被宣告(stated),但是沒有發生記憶體分配。

       如果一個程式由好幾個檔案組成,變數在file1中定義(defined),在file2,file3……中使用,那麼需要在file2和file3中使用extern宣告來連線變數。通常的做法是:將變數和函式的extern宣告放在一個單獨的檔案中,也就是傳說中的標頭檔案(header),然後用#include來載入到每一個原始檔之前。

        extern variable可以簡化引數傳遞(communication-argument)列表,使得其簡短且總是可用。不好的地方是:即使你不想用,它們也總是在那裡。過於依賴external variables會使得程式的資料聯絡不那麼明顯,變數可能會被意外地,或者無意地改變了,這就導致程式難以修改。

         這裡的specialized version不如第一個版本,部分是因為上述原因,還因為將兩個函式各自的變數捆綁在一起,破壞了函式的一般性。