库文件中getline函数的声明已经存在

时间:2022-05-08 10:06:05
 

/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不如第一个版本,部分是因为上述原因,还因为将两个函数各自的变量捆绑在一起,破坏了函数的一般性。