C与指针-第一章scanf\strncpy\strcpy\memcpy

第一章的主要重点是,如何从键盘进行输入、以及相应的字符串拷贝。
这里主要用到四个C的基础API–scanf\strcpy\strncpy\memcpy

scanf
作用: 是格式输入函数,即按用户的制定格式从键盘上把数据输入到制定变量中
头文件: #include
调用形式:scanf(“<格式说明字符串>”,<变量地址>);
注意第二个参数是一个地址,记得加&符号,假如你是一个数组,不需要加入&符号,如果是一个数组带下表,需要加上
int column[8];
int num;
scanf(“%d”,&num)
scanf(“%d”,coloumn);
scanf(“%d”,&coloumn[1]);

例如:
scanf(“%d %d”,&a,&b);
如果a和b都被成功读入,那么scanf的返回值就是2
如果只有a被成功读入,返回值为1
如果a和b都未被成功读入,返回值为0
如果遇到错误或遇到end of file,返回值为EOF。
且返回值为int型.

&a,&b,&c中的&是地址运算符,&a指a在内存中的地址。scanf的作用是:按照a,b,c的内存地址将输入的数据存到a,b,c中去。变量a,b,c的地址是在编译连续阶段分配的(存储顺序由编译器决定)。

注意部分:
如果scanf中%d是连着写的如“%d%d%d”,在输入数据时,数据之间不可以加逗号,只能是空格或tab键或者回车键——“2 3 4” 或 “2(按tab)3(按tab)4(按tab)”。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“2,3,4”.

相关输入格式
变量 类型
%d int
%ld long
%f float
%lf double
%c char
%s char数组

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>

int main(void)
{

int a;
float b;
char c;
scanf("%d,%f,%c",&a,&b,&c);
printf("a=%d,b=%f,c=%c\n",a,b,c);
scanf("%d%f %c",&a,&b,&c);
printf("a1=%d,b1=%f,c1=%c\n",a,b,c);
return 0;
}

输入:

1
2
3
4
1,2.3,d //输入
a=1,b=2.300000,c=d //输出
1 2.4 e //输入
a1=1,b1=2.400000,c1=e //输出

  1. strcpy函数:顾名思义字符串复制函数:原型:extern char strcpy(char dest,char *src); 功能:把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间,返回dest(地址中存储的为复制后的新值)。要求:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
    一般函数原型实现方式:
    1
    2
    3
    4
    5
    6
    7
    8
    char * strcpy(char * strDest,const char * strSrc)
    {

    char * strDestCopy=strDest; //[3]
    if ((strDest==NULL)||(strSrc==NULL)) //[1]
    throw "Invalid argument(s)"; //[2]
    while ((*strDest++=*strSrc++)!='\0'); //[4]
    return strDestCopy;
    }

该函数的参数是字符指针,也就是可以是字符串变量和字符数组,因为它们的变量名代表首字符地址。字符串默认有一个null结束符,字符数组没有。所以此处需要注意:因为src要求有null结束符,所以字符数组的长度必须大于等于src包含null结束符的总长度。例如,char* src=”abcd”; char dest[5]; 这里dest的长度就至少为5。

  1. strncpy函数:多个n代表可以指定字符个数进行赋值。原型:char strncpy(char dest, char src, size_t n); 功能:将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。要求:如果n > dest串长度,dest栈空间溢出产生崩溃异常。该函数注意的地方和strcpy类似,但是n值需特别注意,
    1)src串长度<=dest串长度,(这里的串长度包含串尾NULL字符)
    如果n=(0, src串长度),src的前n个字符复制到dest中。但是由于没有NULL字符,所以直接访问dest串会发生栈溢出的异常情况。这时,一般建议采取memset将dest的全部元素用null填充,如:memset(dest,0,7)(7为从dest起始地址开始前7个位置填充null,dest可以为字符指针和数组名)。注意:char
    pc=”abc”; char chs[5]; sizeof(pc)为4(包含null)(有些编译器不行),sizeof(chs)为5。
    如果n = src串长度,与strcpy一致。
    如果n = dest串长度,[0,src串长度]处存放于desk字串,(src串长度, dest串长度]处存放NULL。
    2)src串长度>dest串长度
    如果n =dest串长度,则dest串没有NULL字符,会导致输出会有乱码。如果不考虑src串复制完整性,可以将dest最后一字符置为NULL。
    所以,一般把n设为dest(含null)的长度(除非将多个src复制到dest中)。当2)中n=dest串长度时,定义dest为字符数组,因为这时没有null字符拷贝。

3、memcpy函数
void memcpy(void s1, const void *s2, size_t n);
说明:
函数memcpy从s2指向的对象中复制n个字符到s1指向的对象中。如果复制发生在两个重叠的对象中,则这种行为未定义。
返回值:
函数memcpy返回s1的值。

memcpy用来在内存中复制数据,由于字符串是以“\0”结尾的,所以对于在数据中包含“\0”的数据只能用memcpy。
Strncpy和memcpy很相似,只不过它在一个终止的空字符处停止。当n>strlen(s1)时,给s2不够数的空间里填充“\0”;当n<=strlen(s1)时,s2是没有结束符“\0”的。

Tianger Ge wechat
如果您喜欢这篇文章,欢迎扫一扫我的微信公众号!