另外关于字符串的另一些博文:
1
2、
Q:如何在一个函数返回字符数组(或者字符串)呢?
参考了一下网友的,大概也就四种方法吧:
下面给出四种返回字符串的方法:
1、 将字符串指针作为函数参数传入,并返回该指针。
2、 使用malloc函数动态分配内存,注意在主调函数中释放。
3、 返回一个静态局部变量。
4、 使用全局变量。
当然各有利弊,就拿一个例子来具体学习下吧。
#include <stdio.h>
#include <string.h>
char* MyString()
{
char str[12];
strcpy(str, "王sir");
return str;
}
int main()
{
char *x;
x = MyString();
printf("%s", x);
return 0;
}
CB编译后 。。。
warning: function returns address of local variable [-Wreturn-local-addr]|
怎么办呢?
#include <stdio.h>
#include <string.h>
char* MyString()
{
static char str[12];
strcpy(str, "王sir");
return str;
}
int main()
{
char *x;
x = MyString();
printf("%s", x);
return 0;
}
注意:
可以这样:
,了解更详细const关键字。
const char* MyString()
{
static char str[12];
strcpy(str, "王sir");
return str;
}
简单吧,简单归简单,但是问题也随之而来了。
由于采用了静态局部变量(位于静态区,程序结束时由系统进行释放),这就导致,如果多次调用这个函数,下一次调用会将上一次调用的结果覆盖掉。
C语言中的库函数,tmpnam()函数、getenv()函数等应该都是采用的这种方法,这也就是为什么,使用这样的函数的时候应该立即将返回结果拷贝一份的原因。
这俩函数是啥?
别急,我也没用过,百度一波。
看例程吧。。
char *tmpnam(char *str)
返回值: 一个指向 C 字符串的指针,该字符串存储了临时文件名。如果 str 是一个空指针,则该指针指向一个内部缓冲区,缓冲区在下一次调用函数时被覆盖。
如果 str 不是一个空指针,则返回 str。如果函数未能成功创建可用的文件名,则返回一个空指针。
#include <stdio.h>
int main()
{
char buffer[L_tmpnam];
char *ptr;
tmpnam(buffer);
printf("临时名称 1: %s\n", buffer);
ptr = tmpnam(NULL);
printf("临时名称 2: %s\n", ptr);
return(0);
}
再来看下:
char *getenv(const char *name)
返回值 该函数返回一个以 null 结尾的字符串,该字符串为被请求环境变量的值。如果该环境变量不存在,则返回 NULL。
同样,直接看例程吧。
#include <stdio.h>
#include <stdlib.h>
int main ()
{
printf("PATH : %s\n", getenv("PATH"));
printf("HOME : %s\n", getenv("HOME"));
printf("ROOT : %s\n", getenv("ROOT"));
return(0);
}
既然局部变量相当于全局变量了,那我们直接定义全局变量当然也是可以的!
#include <stdio.h>
#include <string.h>
char str[12];
char* MyString()
{
strcpy(str, "王sir");
return str;
}
int main()
{
char *x;
x = MyString();
printf("%s", x);
return 0;
}
将其作为字符指针传入,特别注意如果此时想让其作为字符指针为参数传入函数,那么它实参本身必须为字符数组。
错误的示范
#include <stdio.h>
#include <string.h>
void MyString(char *str)
{
strcpy(str, "王sir");
}
int main()
{
char *x;
MyString(x);
printf("%s", x);
return 0;
}
正确的示范
#include <stdio.h>
#include <string.h>
void MyString(char *str)
{
strcpy(str, "王sir");
}
int main()
{
char x[10];
MyString(x);
printf("%s", x);
return 0;
}
这种缺点,也可直接从主函数中看到,对应的x,即字符数组的内存要足够。
防止意外的溢出,可以这样。指定长度。
#include <stdio.h>
#include <string.h>
void MyString(char *str, int len)
{
strncpy(str, "王sir", len-1);
str[len-1] = '\0';
}
int main()
{
char x[10];
MyString(x, 10);
printf("%s", x);
return 0;
}
关于内存分配函数再来回忆一波。。
void *malloc(unsigned size)
eg: 关于sizeof和strlen的区别戳这里。
int p = (int )malloc(n*sizeof(int))
申请对应该机器可存放n个int的内存空间。
对了,还有个colloc函数,函数原型为:
void *calloc(unsigned n, unsigned size);
它和malloc函数的区别还有,calloc可以自己置0,但是malloc需要借助memset或者循环手动置0。
memset(a, 0, sizeof(a))
直接对应都是字符指针也无妨。。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* MyString()
{
char *str;
str = (char *)malloc(10);
strcpy(str, "王sir");
return str;
}
int main()
{
char *x;
x = MyString();
printf("%s", x);
free(x);
return 0;
}
参考:
1、
2、