映月读书网 > C语言解惑 > 8.3 对库函数的作用理解不对 >

8.3 对库函数的作用理解不对

【例8.4】下面程序中将姓和名分别输出在两行,改正这个错误。


#include <stdio.h>
#include <string.h>
int main
( 
)
{
      char first_name[100]
;
      char last_name[100]
;
      char full_name[100]
;
      printf
(\"First name
: \"
);
      fgets
(first_name
,sizeof
(first_name
),stdin
);
      printf
(\"Last name
: \"
);
      fgets
(last_name
,sizeof
(last_name
),stdin
);
      strcpy
(full_name
, \" \"
);
      strcpy
(full_name
,first_name
);
      strcat
(full_name
,last_name
);
      printf
(\"Full name
: %s\"
,full_name
);
      return 0
;
}
  

【解答】下面是程序的运行示范:


First name
: Wang
Last name
: Guoying
Full_name
: Wang
Guoying
  

库函数fgets在读取字符时,会自动在尾部加入“n”。用strcat函数连接两个字符串时,中间就多了一个换行符。解决的办法就是将“n”换成空格。用strlen函数求出“n”的位置,这个位置的数组下标就是字符串长度-1。下面的程序将这个换行符换成空格。


#include <stdio.h>
#include <string.h>
int main
( 
)
{
       char first_name[100]
;
       char last_name[100]
;
       char full_name[100]
;
       int i=0
;
       printf
(\"First name
: \"
);
       fgets
(first_name
,sizeof
(first_name
),stdin
);
       printf
(\"Last name
: \"
);
       fgets
(last_name
,sizeof
(last_name
),stdin
);
       strcpy
(full_name
, \" \"
);
       strcpy
(full_name
,first_name
);
       i=strlen
(first_name
)-1
;
       strcat
(full_name
,last_name
);
       full_name[i]=\' \'
;
       printf
(\"Full name
: %s\"
,full_name
);
       return 0
;
}
  

运行示范如下:


First name
: Wang
Last name
: Guoying
Full_name
: Wang Guoying
  

当然,也可以先处理换行符,即把换行符改为空格,然后再连接。


//
先处理换行符再连接字符串的程序
#include <stdio.h>
#include <string.h>
int main
( 
)
{
       char first_name[100]
;
       char last_name[100]
;
       char full_name[100]
;
       int i=0
;
       printf
(\"First name
: \"
);
       fgets
(first_name
,sizeof
(first_name
),stdin
);
       printf
(\"Last name
: \"
);
       fgets
(last_name
,sizeof
(last_name
),stdin
);
       strcpy
(full_name
, \" \"
);
       strcpy
(full_name
,first_name
);
       i=strlen
(first_name
)-1
;
       full_name[i]=\' \'
;                       //
先处理换行符再连接字符串
       strcat
(full_name
,last_name
);
       printf
(\"Full name
: %s\"
,full_name
);
       return 0
;
}
  

【例8.5】分析下面程序中存在的错误。


#include <stdio.h>
#include <string.h>
int main
( void 
)
{
     char string[80]
;
     strcpy
( string
, \"Hello world\0\" 
);
     return 0
;
}
  

【解答】库函数strcpy的原型为


char *strcpy
( char *strDestination
, const char *strSource 
);
  

它将strSource指向的字符串(包含结束标志)拷贝到strDestination指向的字符数组中。所以程序中多了结束符号“\0”。当然结果是一样的,但说明程序编写者对该函数的理解不够。于此类似的还有strcat函数。它的函数原型为


char *strcat
( char *strDestination
, const char *strSource 
);
  

它将strSource指向的字符串连接到strDestination指向的字符数组的后面,连接规则为:假定原来的数组有足够的空间存储连接后的字符串,被连接字符串覆盖原字符串最后的空白终止符,用自己的结束符作为新字符串的结束符,例8.6说明了它的用法。

【例8.6】下面程序很简单,虽然编译给出错误信息,也能产生执行文件,但运行时出现错误。找出原因并修改运行程序。


#include <stdio.h>
#include <string.h>
const char PATH=\"d
:/user/my\"
;
char *full_name
( char 
);
int main
( 
)
{
         printf
(\"Full name is
: %sn\"
,full_name
(\"data\"
));
         return 0
;
 }
 char *full_name
(const char name
)
 {
        char file_name[100]
;
        strcpy
(file_name
,PATH
);
        strcat
(file_name
,\'/\'
);
        strcat
(file_name
,name
);
        return 
(file_name
);
 }
  

【解答】这个程序不长,问题也不少。const定义的是字符,但确赋给字符串。正确的是定义为


const char PATH=\"d
:/user/my\"
;
  

虽然也可以使用如下的


#define PATH \"d
:/user/my\"
  

宏定义方式,但推荐使用const。

函数声明与定义不符合,定义使用const,声明也必须相同。即


char *full_name
(const char 
);
  

对库函数strcat的使用不对,\'/\'是字符,strcat要求的是字符串。应改为


strcat
(file_name
,\"/\"
);
  

full_name函数里定义的普通字符数组file_name在结束运行时就失去作用,必须将它定义为静态数组。下面是修改后的程序。


#include <stdio.h>
#include <string.h>
const char PATH=\"d
:/user/my\"
;
char *full_name
(const char 
);
int main
( 
)
{
        printf
(\"Full name is
: %sn\"
,full_name
(\"data\"
));
        return 0
;
}
char *full_name
(const char name
)
{
        static  char file_name[100]
;
        strcpy
(file_name
,PATH
);
        strcat
(file_name
,\"/\"
);
        strcat
(file_name
,name
);
        return 
(file_name
);
}
  

程序运行结果为


Full name is
: d
:/user/my/data
  

【例8.7】分析下面程序中存在的错误。


#include <stdio.h>
#include <string.h>
void main
( void 
)
{
   char string[80]
;
   char str2=\"strcat
!\" 
;
   strcpy
( string
, \"Hello world from \" 
);
   strcat
( string
, \"strcpy \" 
);
   strcat
( string
, \"and \" 
);
   strcat
( string
, str2 
);
   printf
(\"
字符串%s
的长度为%d
。n\"
,string
,strlen
(string
)+1
);
   strcpy
( string
, str2 
);
   printf
(\"
字符串%s
的长度为%d
。n\"
,string
,strlen
(string
)+1
);
   return 
;
}
  

【解答】strlen的函数原型为


size_t strlen
( const char *string 
);
  

size_t是unsigned integer,即strlen函数返回字串的长度(字符串的个数),这个长度不包含字符串的结束标志\'\0\',也就是不是存储字符串的长度。将两个输出语句中的“+1”去掉即可。例如:


printf
(\"
字符串%s
的长度为%d
。n\"
,string
,strlen
(string
));
  

修改后的运行结果如下。


字符串Hello world from strcpy and strcat
!的长度为35
。
字符串strcat
!的长度为7
。
  

结论:必须正确理解库函数的原型。