字符串输入输出

字符串的定义

//字符串的定义和赋值 
char a[10];  //一维字符数组
char b[5][10];  //二维字符数组
char c[20]={'c', '  ', 'p', 'r', 'o', 'g', 'r', 'a','m'};  // 给部分数组元素赋值
char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' };  //对全体元素赋值时可以省去长度

/*字符数组只有在定义时才能将整个字符串一次性地赋值给它,
一旦定义完了,就只能一个字符一个字符地赋值了
*/ 
/*
char str[ ]="I am happy";
上述这种字符数组的整体赋值赋值,字符数组的赋值只能对其元素一一赋值,下面的赋值方法是错误的
不是用单个字符作为初值,而是用一个字符串(注意:字符串的两端是用双引号“”而不是单引号‘'括起来的)作为初值。显然,这种方法更直观方便。(注意:数组str的长度不是10,而是11,这点请务必记住,因为字符串常量"I am happy"的最后由系统自动加上一个'\0')
*/
char str[7];
str = "abc123";  //错误
//

//正确如下
str[0] = 'a'; str[1] = 'b'; str[2] = 'c';
str[3] = '1'; str[4] = '2'; str[5] = '3';

//字符串的结束是以'\0'为末尾结束的
//逐个字符地给数组赋值并不会自动添加’\0’

考虑等价问题;

通过字符数组赋值
char c1[]={'I',' ','a','m',' ','h','a','p','p','y'};
直接字符数组整体赋值
char c2[]="I am happy";
int i1=sizeof(c1);
int i2=sizeof(c2);
printf("%d\n",i1);//10
printf("%d\n",i2);//11
这里就是很明显的区别字符串的长度

字符串的长度

	//字符串的结束是以'\0'为末尾结束的
	//逐个字符地给数组赋值并不会自动添加’\0’
	//字符串的结束是以'\0'为末尾结束的
	//逐个字符地给数组赋值并不会自动添加’\0’
 	char str1[] = {'a', 'b', 'c'};//数组 str 的长度为 3,而不是 4,因为最后没有'\0'。
	char str2[] = {"abc"};
	printf("%d\n",sizeof(str1));//输出的为3 
	printf("%d\n",sizeof(str2));//输出的为4
	
	//当用字符数组存储字符串时,要为’\0’留个位置;这意味着,字符数组的长度至少要比字符串的长度大 1。
	//char str[7] = "abc123";
	//但是 字符串的长度就是字符串包含了多少个字符(不包括最后的结束符’\0’)
	//例如"abc"的长度是 3,而不是 4

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WAdCzkTd-1669543392135)(C:\Users\12103\Desktop\c语言学习笔记\assets\1668008359688.png)]

字符串的输出

在C语言中,有两个函数可以在控制台(显示器)上输出字符串,它们分别是:

puts():输出字符串并自动换行,该函数只能输出字符串。
printf():通过格式控制符%s输出字符串,不能自动换行。
#include
#include
int main()
{
	char str[20]={"zhangweidong"};
	puts(str);//末尾有自动换行 
	
	printf("\n%s",str);//末尾无换行 
	return 0;
 } 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-84qmysOh-1669543392136)(C:\Users\12103\Desktop\c语言学习笔记\assets\1668008652845.png)]

注意:输出字符串时只需要给出名字,不能带后边的[ ],例如,下面的两种写法都是错误的:

printf("%s\n", str[]);
puts(str[10]);

字符串的输入

在C语言中,有两个函数可以让用户从键盘上输入字符串,它们分别是

scanf():通过格式控制符%s输入字符串。
gets():直接输入字符串,并且只能输入字符串。

scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。

gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束。

   #include 
    int main(){
        char str1[30] = {0};
        char str2[30] = {0};
        char str3[30] = {0};
        //gets() 用法
        printf("Input a string: ");
        gets(str1);
        //scanf() 用法
        printf("Input a string: ");
        scanf("%s", str2);
        scanf("%s", str3);//因为读到空格就停止了所以需要读入两次
       
        printf("\nstr1: %s\n", str1);//输出C C++ Java Python↙
        printf("str2: %s\n", str2);//输出PHP
        printf("str3: %s\n", str3);//输出JavaScript
        return 0;
    }

运行结果:

//输入
Input a string: C C++ Java Python↙
Input a string: PHP JavaScript↙
//输出
str1: C C++ Java Python
str2: PHP
str3: JavaScript

第一次输入的字符串被 gets() 全部读取,并存入 str1 中。
第二次输入的字符串,前半部分被第一个 scanf() 读取并存入 str2 中,后半部分被第二个 scanf() 读取并存入 str3 中。

注意:scanf() 在读取数据时需要的是数据的地址,这一点是恒定不变的,所以对于 intcharfloat 等类型的变量都要在前边添加&以获取它们的地址。但是因为字符串名字或者数组名字在使用的过程中一般都会转换为地址,所以再添加&就是多此一举了。

就目前学到的知识而言,int、char、float 等类型的变量用于 scanf() 时都要在前面添加&,而数组或者字符串用于 scanf() 时不用添加&,

字符串的表示形式

在C语言中,可以用两种方法表示和存放字符串:

  • 用字符数组存放一个字符串
  • 字符指针指向一个字符串

C语言对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量,程序在定义字符串指针变量str时存放字符串的字符数组的首地址)赋给str。

两种表示方式的字符串输出都用

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

输出方式参考字符串的输入

%s表示输出一个字符串,给出字符指针变量名str(对于第一种表示方法,字符数组名即是字符数组的首地址,与第二种中的指针意义是一致的),则系统先输出它所指向的一个字符数据,然后自动使str自动加1,使之指向下一个字符…,如此,直到遇到字符串结束标识符 " \0 "。

字符数组与字符指针

虽然用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混为一谈。

字符数组由若干个元素组成,每个元素放一个字符;而字符指针变量中存放的是地址(字符串/字符数组的首地址),绝不是将字符串放到字符指针变量中(是字符串首地址)

赋值方式:

对字符数组只能对各个元素赋值,不能用以下方法对字符数组赋值char str[14];

str="I love China"; (但在字符数组初始化时可以,即char str[14]="I love China";) 而对字符指针变量,采用下面方法赋值:

char* a;

a="I love China";

或者是 char* a="I love China"; 都可以

对字符指针变量赋初值(初始化)

char* a="I love China";
等价于:

char* a;
a="I love China";

而对于字符数组的初始化

char str[14]="I love China";

不能等价于:

char str[14];
str="I love China"; (这种不是初始化,而是赋值,而对数组这样赋值是不对的)

如果定义了一个字符数组,那么它有确定的内存地址;而定义一个字符指针变量时,它并未指向某个确定的字符数据,并且可以多次赋值。

字符串相关的函数

strlen()

常用于统计字符串的长度。在这里要注意的是,它会从内存的某个位置开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’),

#include 
#include 

int main(void){
    char str[10000] = "Hello,world";//字符数组直接定义
    printf("this string has %d characters",strlen(str));//11
    return 0;
}
///
输出
this string has 11 characters

strcat()

用于拼接字符串,该函数接受两个字符串作为参数。该函数把第2个字符串的备份附加在第1个字符串末尾,并把拼接后形成的新字符串作为第1个字符串,第2个字符串不变。strcat()函数的类型是char *(指向char的指针)。strcat()函数返回第一个参数,即拼接第2个字符串后的第1个字符串的地址

#include 
#include 

int main(void){
    char str1[1000] = "Hello";
    char str2[1000] = "world";
    strcat(str1,str2);//把str2链接到str1后面
    puts(str1);
    return 0;
}
///
输出
Helloworld

strncat()

strncat()函数一共接受3个参数,例如如下写法

strncat(str1,str2,13);

的含义为将str2字符串内的内容附加给str1,在加到第13个字符或者空字符时停止。 所以,算上空字符,str1数组应该足够大,用以容纳原始字符串(不包含空字符)、添加原始字符串在后面的13个字符和末尾的空字符。

#include 
#include 
#include 

int main(void){
    char str1[1000] = "Hello ";
    char str2[1000] = "world";
    strncat(str1,str2,2);
    puts(str1);
    return 0;
}
///
输出
// Hello wo

strcmp()

用于将用户的响应与已存储的字符串作比较。(注意它比较的对象是字符串,不是字符)

要注意这里c语言里面,不可以用>,<,=这些运算符去比较字符数组

但是对于c++来说这里是进行了方法的重载的

所有这里strcmp函数是我们用来进行字符串比较的方法;

#include 
#include 

int main(void){
    char str1[20] = "Hello";
    char str2[20] = "Hello";
    char str3[20];
    if(strcmp(str1,str2) == 0)printf("str1 is same as str2\n");//ture
    printf("please input a string to str3:\n");
    gets(str3);
    if(strcmp(str3,str1) == 0)printf("str3 is same as str1\n");
    else if(strcmp(str3,str1) == 1)printf("str3 is different to str1\n");
    return 0;
}
// output_1:
/*
str1 is same as str2
please input a string to str3:
hello
str3 is different to str1
*/


// output_2:
/*
str1 is same as str2
please input a string to str3:
Hello
str3 is same as str1
*/

strcpy()

用于拷贝字符串。其返回值为char *

#include 
#include 

int main(void){
    char str1[20];
    char str2[20] = "Hello World.";
    strcpy(str1,str2); // 将str2的内容copy到str1中
    puts(str1);
    return 0;
}
// output:
// Hello World.

strncpy()

三个参数

函数的第三个参数指明可拷贝的最大字符数。

#include 
#include 

int main(void){
    char str1[20];
    char str2[20] = "Hello World.";
    strncpy(str1,str2,9); // 将str2的内容copy到str1中
    puts(str1);
    return 0;
}
// output:
// Hello wor

sprintf()

该函数类似printf(),但sprintf()的功能是将数据写入字符串,而不是打印在显示器上。因此,该函数可以将多个元素组合成一个字符串。sprintf()的第一个参数是目标字符串的地址。其余参数和printf()相同,即格式字符串和待写入项的列表。

#include 
#include 

int main(void){
    char str1[20];
    int a = 114514;
    sprintf(str1,"Hello %d",a);
    puts(str1);
    system("pause");
    return 0;
}
// output:
// 114514

strstr()

一个用于查找的函数

该函数返回指向s1字符串中s2字符串出现的首位置。如果在s1中没有找到s2,则返回空指针。

#include 
#include 
#include 

int main(void){
    char str1[20] = "Hello,world";
    char str2[20] = "world";
    char *str3;

    str3 = strstr(str1,str2);
    
    printf("the string is:%s",str3);
    system("pause");
    return 0;
}
// output:
// the string is:world

strstr()

一个用于查找的函数

该函数返回指向s1字符串中s2字符串出现的首位置。如果在s1中没有找到s2,则返回空指针。

#include 
#include 
#include 

int main(void){
    char str1[20] = "Hello,world";
    char str2[20] = "world";
    char *str3;

    str3 = strstr(str1,str2);
    
    printf("the string is:%s",str3);
    system("pause");
    return 0;
}
// output:
// the string is:world

你可能感兴趣的:(我的c语言学习,c语言)