天天看点

C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

文章目录

  • 1.字符类型
  • 2.字符读取
    • 1.scanf()函数
    • 2.getchar和putchar函数用法
  • 3.字符串
    • 1.自符串的定义:
  • 2.strlen();和sizeof();的区别
    • 3.注意出现野指针造成非法内存访问,出现段错误。
    • 4.malloc 动态开辟内存空间
    • 5.字符串的操作函数:(调用函数时需要包含文件#include<string.h>)
    • 6.自己实现的字符串操作函数

1.字符类型

char是一种整数,也是一种特殊的类型——字符。用单引号表示的字符字面量:‘a’,'1’也是一个字符,printf和scanf里面用%c来输入输出字符。

2.字符读取

1.scanf()函数

用法

%d说明我们现在要读入一个整数了,scanf这个函数会读入下一个整数,读到的结果赋值给指定变量,要注意指定变量前面的&

如果要读入输入的数据,就必须严格按照""中的格式输入,如:

int main()
{
 int a,b;
 scanf("%d,%d",&a,&b);
 printf("%d %d\n",a,b );
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

若不严格按照格式输入,则会导致接收错误

  • scanf语句的原理

    scanf并不会直接从我们的键盘输入中读取数据,我们从键盘输入的数据先存储在输入缓冲区中,当按下回车键后,即输入缓冲区遇到回车符时,程序才会在输入缓冲区中读取数据,scanf读取到空格、tab或者回车符的时候停止读取。

    scanf语句读取完数字后,会把后面的空格也读取掉。如果后面有变量来接收,读取后就会把空格赋值给对应的变量,如果没有变量来接收,那么仅仅是读取,不会进行赋值操作。值得注意的是,scanf只有在读取完数字后会继续把后面的空格读取掉

    如下例:

int main()
{
    char word[8];
    scanf("%s",word);
    printf("%s\n",word);
    
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

这说明读取完字符o后,并没有将后面的空格读取出来,遇到空格就直接停止读取了。

2.getchar和putchar函数用法

(1)getchar函数

函数格式: int getchar()

所在头文件: <stdio.h>

函数功能: 从输入缓冲区中读取单个字符

函数返回值: 成功时为获得的字符,失败时为 EOF 。

(2)putchar函数

函数格式: int putchar(int ch)

所在头文件: <stdio.h>

函数功能: 输出字符到标准输出上,等价于 putc(ch, stdout)

函数参数: ch,表示要写入的字符,可以是字符常量,转义字符,可以是介于0~ 127之间的一个十进制整型数(包含0和127,超过127就不是ASCII码了),当参数为一个介于0~127(包括0及127)之间的十进制整型数时,它会被视为一个ASCII代码,输出该ASCII代码对应的字符,也可以是一个字符变量。

参数为是一个字符,但参数却是int型,这表示1字节的字符存在4字节大小的内存中。

或者换个理解方式,字符对应的ASCII码值用int型参数来接收。

函数返回值:

成功时,返回参数的ASCII码值。

失败时,返回 EOF 并设置 stdout 上的错误指示器。

3.getchar和putchar函数工作原理:

getchar()用于从键盘输入中读取单个字符,当我们连续输入多个字符时,第一个getchar()读取第一个字符,后续的getchar()依次读取后续的字符,当getchar()读取到EOF或者读取到回车时停止执行。

while ((ch = getchar()) != EOF) {

		putchar(ch);

	}

           
#include<stdio.h>

int main()
{
	char ch = ' ';

	while ((ch = getchar()) != EOF) {

		putchar(ch);

	}

	return 0;
}

           

我们输入abc按下回车后,

输入缓冲区中的内容:abc\n

由于遇到\n,因此getchar开始从输入缓冲区中读取字符,先读取a,满足输出while循环条件,可以输出,先存储到输出缓冲区中,然后读取b,满足输出while循环条件,可以输出,先存储到输出缓冲区中,然后读取c,满足输出while循环条件,可以输出,先存储到输出缓冲区中,最后读取\n,满足输出while循环条件,可以输出,先存储到输出缓冲区中。

此时输出缓冲区中的内容:abc\n

由于输出缓冲区遇到了\n,所以进行一次系统调用,将输出缓冲区的内容直接输出到标准输出上。

C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

3.字符串

1.自符串的定义:

char* str=” Zhang ”;

相当于

char str []=”Zhang”;

这里直接使用指针因为数组的名称相当于首元素的地址。

  • 注意:

    上述方法定义

    char* str=” Zhang ”;

    是字符串的常量,内容不可以修改。

    若定义为:

    char str []=”Zhang”;

    则为字符串变量,可以修改!
  • 调用时:

    printf(“%s”,str);

    //调用时直接用%s占位符即可。
  • 字符串在内存中的存储方式:

    字符串在存储时,除了有效字符以外,还会自动在后面补一个’\0’的结束标志。

2.strlen();和sizeof();的区别

计算字符串有效字符的个数用函数 strlen();而不是sizeof();

  • sizeof();是C语言得关键字,而strlen();是函数
strlen();在计算字符大小时遇到’\0’就停止了计数。
sizeof 计算字符数组大小时计算全部数组大小,即:
char data [128] = “hello”;
sizeof(data) = 128;
strlen(data) = 5;
           

3.注意出现野指针造成非法内存访问,出现段错误。

形如:

char*pstr;
scanf(“%s”,pstr);
puts(pstr);
           

便会造成非法内存访问。定义出来的pstr 成为了一个野指针,指针变量里面所存放的东西未知且系统没有给空间。

解决方法:

方法1:(直接用字符数组并在内存放128个’\0’)

`char pstr[128]=’\0’;`//申请空间并做了初始化,把每个元素都初始化为’\0’
scanf(“%s”,pstr);
puts(pstr);
           

方法2:(用malloc函数开辟空间)

char*pstr=(char*)malloc(128);
           

4.malloc 动态开辟内存空间

与malloc 相关的函数

(Linux下)

void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
           

void *malloc(size_t size);

分配所需的内存空间。并返回一个指向它的指针

void free(void *ptr);

释放,防止内存泄露 当内存不再使用的时候,应使用free()函数将内存块释放掉。

void *calloc(size_t nmemb, size_t size);

calloc(10 , sizeof(int)) calloc在返回在堆区申请的那块动态内存的起始地址之前,会将每个字节都初始化为0

void *realloc(void *ptr, size_t size);

尝试重新调整之前malloc或calloc所分配的指针所指向内存块的大小

5.字符串的操作函数:(调用函数时需要包含文件#include<string.h>)

(1)

puts(str);

//输出字符串函数。(此函数可以自动加换行\n)

#include<stdio.h>
#include<string.h>


int main()
{
     char * str = "hello";
     puts(str);

    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(2)

gets(str);

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    char *str;
    str = (char *)malloc(32);
    gets(str);
    printf("str:%s\n",str);
    return 0;
}

           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(3)

void *memset(void *s, int c, unsigned long n);

第一个参数

void* mem_loc

:已开辟内存空间的首地址,通常为数组名或指针,由于其为

void*

,故函数能为任何类型的数据进行初始化。

第二个参数

int c

:初始化使用的内容,取器低字节部分。

第三个参数

size_t n

:需要初始化的字节数。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char char_arr[5];
    int int_arr[10];
    int* int_malloc_ptr = (int*)malloc(sizeof(int) * 15);

    memset(char_arr, 0, sizeof(char_arr));          // 数组名可以使用sizeof(arrName), 1 * 5 = 5
    memset(int_arr, 0, sizeof(int_arr));            // 4 * 10 = 40
    memset(int_malloc_ptr, 0, sizeof(int) * 15);    // 4 * 15 = 60

    printf("%s\n",char_arr);

    return 0;
}

           

(4)

strcpy(str1,str2);

字符串拷贝

把str2的内容拷贝到str1中

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *str1 = "Hello World";
    char *str2;
    strcpy(str2,str1);
    printf("str2:%s\n",str2);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(5)

strncpy(str1,str2,int n);

把str2的内容拷贝到str1中,拷贝n个字符

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *str1 = "Hello World";
    char *str2;
    strncpy(str2,str1,6);
    printf("str2:%s\n",str2);
    return 0;
}

           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(6)

strcat(str1,str2);

//拼接函数 把str1和str2接到一起。

注意

由于要改变字符串需要将字符串定义为数组形式

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char str1[] = "Hello ";
    char str2[] = "World";
    strcat(str1,str2);
    printf("str1:%s\n",str1);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(7)

strlwr(str);

将一段字符转为小写

注意定义str时只能用数组定义

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char str1[] = "HELLO";
    strlwr(str1);
    printf("str1:%s\n",str1);
    return 0;
}

           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(8)

strupr(str);

将一段字符转为大写。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char str1[] = "hello";
    strupr(str1);
    printf("str1:%s\n",str1);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(9)

strtok(str1,”,”);

字符切割 将str1以,为结束标志切割

注意只能分割出来第一个字符串若想继续分割则要继续调用strok()调用而且要把目标字符串改成NULL strok(NULL,”,”);

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char str1[]="hello,world";
    char*p=NULL;
    p=strtok(str1,",");
    puts(p);//注意只能分割出来第一个字符串若想继续分割则要继续调用strok()调用而且要把目标字符串改成NULL  strok(NULL,”,”);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char str[]="hello,world";
    char*p=NULL;
    p=strtok(str,",");
    puts(p);
    p=strtok(NULL,",");
    puts(p);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(10)

strchr();

检索字符在一个字符串中出现的位置

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char*str="hello world";
    char c='w';
    char*p=NULL;
    //str 要被检索的字符串,c在str中要搜索的字符,返回值 返回字符串中第一次出现该字符的指针。若字符串中不包含该字符则返回NULL。
    p=strchr(str,c);
    puts(p);
    system("pause");
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

可见得到了第一次出现的’w’指针,并返回"world"字符串

(11)

strstr();

检索子串在一个字符串中出现的位置,并返回子串指针。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char*str="hello world!";
    char*p=NULL;
    char*substr="wor";
    p=strstr(str,substr);
    if(p==NULL)
    {
        printf("没有找到\n");
        
    }
    else{
    puts(p);
    }
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(12)

int ret =strcmp(char *s1,char*s2);

  • 功能:比较两个字符串

(1). 如果两个字符串相等,则返回0;

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char* str1 = "helloworld";
    char* str2 = "helloworld";
    int ret;
    ret = strcmp(str1,str2);
    printf("%d\n",ret);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(2). 若str1大于str2,返回一个正数,这个正数不一定是1;

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char* str1 = "helloworld";
    char* str2 = "hellow!";
    int ret;
    ret = strcmp(str1,str2);
    printf("%d\n",ret);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别

(3). 若str1小于str2,返回一个负数,这个数不一定是-1

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    char* str1 = "helloworld!";
    char* str2 = "hello!";
    int ret;
    ret = strcmp(str2,str1);
    printf("%d\n",ret);
    return 0;
}
           
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char* str1 = "hello world";
    char* str2 = "helloworld";
    int ret;
    ret = strcmp(str1,str2);
    printf("%d\n",ret);
    return 0;
}
           
C语言学习-字符学习1.字符类型2.字符读取3.字符串2.strlen();和sizeof();的区别
  • 注意:若字符串中存在空格,则以空格前的字符串进行比较:

(13)断言函数:

#include <assert.h>

assert的作用是现计算表达式expression,如果其值为假(0)则会打印错误消息终止运行:

6.自己实现的字符串操作函数

(1)strcpy

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* myStrcpy(char *des_str,char *src_str)
{

    assert(des_str != NULL&&src_str != NULL);
	char *temp = des_str;
    while(*src_str != '\0'){
		*des_str++ = *src_str++;
    
    }
    *des_str = '\0';
    
    return temp;



}

int main()
{
	char * str = "hello world!";
    char str1[128] = {'\0'};
    myStrcpy(str1,str);
    printf("%s\n",str1);
    
	system("pause");
	return 0;
}

           

(2)strcat

char *myStrcat(char *des_str,char *src_str)
{
    assert(des_str!=NULL&&src_str!=NULL);
    char *temp = des_str;
    while(*des_str != '\0'){
        des_str++;
    }
    
    while((*des_str++ = *src_str++)!='\0');
    *des_str = '\0';

    return temp;

}

int main()
{
    char *str = "world!";
    char str1[32] = "hello ";
    char *p2;
   
    p2 = myStrcat(str1,str);
    printf("%s\n",p2);
    
    system("pause");
    return 0;
}

           

(3)strcmp

int myStrcmp(char *str1,char *str2)
{
    int str1Len;
    int str2Len;
    while(*str1!='\0'){
        str1++;
        str1Len++;
    }
    while(*str2!='\0'){
        str2++;
        str2Len++;
    }
    if(str1Len < str2Len){
        return -1;
    }else if (str1Len == str2Len)
    {
        return 0;
    }else if(str1Len > str2Len){
        return 1;
    }

}
           

继续阅读