C语言——字符串

简介: 字符串

字符串输入

如果想把一个字符串读取到程序中,必须首先预留存储字符串的空间,然后使用输入函数来获取这个字符串,C库提供了三个读取字符串的函数:scanf()、gets()和fgets()。

创建存储空间

可以通过数组(char name[10])来分配存储空间,也可以通过C语言动态内存分配函数来动态分配存储空间。

char*name;

scanf("%s", name);

如果通过上面的代码来创建存储空间,可能会通过编译器,但是在读入name的时候,name会覆盖程序中的数据和代码,并可能导致程序异常终止。这个是 因为scanf()把信息复制到由name指定的地址中,而在这种情况下,参数是个 未被初始化的指针,name可能指向任何地方。

gets()函数

gets()(get string)函数对于交互式程序非常方便,它从系统的标准输入设备(通常是键盘)获得一个字符串。因为字符串没有预定的长度,所以gets()函数通过判断遇到的第一个换行符(\n)结束输入,按回车键可以产生这个字符。它读取换行符之前(不包括换行符)的所有字符,并在这些字符后添加一个空字符(\0)。

[clef@rhel6164c]$cattest1.c

#include<stdio.h>

#define MAX 81

intmain(void)

{

   charname[MAX];

   char*ptr; //指向char的指针

   printf("Please input your name.\n");

   ptr=gets(name); //使用一个地址吧字符串赋值给name

   //gets()函数使用return关键字返回字符串的地址

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

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

   return0;

}

编译&运行:

[clef@rhel6164c]$gcctest1.c

/tmp/ccDJ9AHw.o: Infunction`main':

//因为gets()函数不检查存储区是否能够容纳实际输入的数据,可以用后面的fgets()函数替换gets()函数

test1.c:(.text+0x1a): warning: the`gets' function is dangerous and should not be used.

[clef@rhel6164c]$ ./a.outPleaseinputyourname.clefname, clef

//这里ptr和name的内容是一样的ptr, clef

如果在gets()函数在读取字符串时 出错或者遇到文件结尾,它就返回一个空(或0)地址,这个空地址被称为 空指针,并且stdio.h里面定义的常量 NULL来表示,可以用下面的代码来进行一些错误检测。

while(get(name) !=NULL)

也可以通过 getchar函数来完成上面的错误检测。

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

注意:空指针和空字符是不一样的,不要混淆。空指针是一个地址,而空字符是一个char类型的数据对象其值为0,数字上都可以用0表示,但是概念不同:NULL是一个指针,而0是一个char类型的常量。

fgets()函数

因为gets()函数不会检查存储区是否能够容纳实际输入的数据,多出来的字符简单地溢出到相邻的内存区,所以上面的代码在编译的时候会有warning。fgets()函数和gets()函数的不同:

  • 它需要第二个参数来说明最大读入字符数。如果这个参数值为n,fgets()就会读取最多n-1个字符或者读完一个换行符为止(因为会自动添加一个空字符(\n)),由这两者中最先满足的那个结束输入。
  • 如果fgets()读取到换行符,就会把它存到字符串里,而不是像gets()那样丢弃。
  • 它还需要第三个参数来说明读哪一个文件,从键盘上读取数据时,可以使用stdin(代表standard input)作为参数,这个标识符在stdio.h中定义。

[clef@rhel6164c]$cattest1.c

#include<stdio.h>

#define MAX 81

intmain(void)

{

   charname[MAX];

   char*ptr;

   printf("Please input your name.\n");

   ptr=fgets(name, MAX, stdin);

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

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

   return0;

}

编译&运行:

[clef@rhel6164c]$gcctest1.c//这里就没有warning出现

[clef@rhel6164c]$ ./a.out

Pleaseinputyourname.

clef

name, clef

//注意这里的换行符,因为fgets()函数没有丢弃输入的换行符

ptr, clef

[clef@rhel6164c]$

scanf()函数

scanf()函数可以使用%s格式来读入一个字符串,scanf()函数和gets()函数的主要区别在于如何决定字符串何时结束。scanf()函数更基于获得单词(get word)而不是获取字符串(get string)。scanf()函数有两种方法决定输入结束,无论哪一种都是遇到的第一个非空白字符开始

  1. 如果使用%s格式,字符串读取到(但不包括)下一个空白字符(比如空格、制表符或换行符)
  2. 如果指定了字段宽度,比如%10s,scanf()函数就会读取10个字符或者直到遇到第一个空白字符,由二者最先满足的那一个终止输入

字符串输出

C语言有三个输出字符串的标准库函数:puts()、fputs()和printf()

puts()函数

puts()函数使用很简单,只需要给出字符串参数的地址,它遇到空字符(\0)就会结束输出(所以必须要有空字符)。puts()函数在显示字符串的时候,会自动在其后添加一个换行符(\n)。

[clef@rhel6164c]$cattest1.c

#include<stdio.h>

#define DEF "I am a #defined string."

intmain(void)

{

   charstr1[80] ="An array was initialized to me.";

   constchar*str2="A pointer was initialized to me.";

   puts("I'm an argument to puts()."); //直接用字符串做参数

   puts(DEF); //用宏定义做参数

   puts(str1);

   puts(str2);

   puts(&(str1[5])); //必须用括号strl1[5],因为str1将会首先结合&,然后在[5]结合,将出错

   puts(str2+4);

   return0;

}

编译&执行:

[clef@rhel6164 c]$ gcc ./test1.c

[clef@rhel6164 c]$ ./a.out

I'm an argument to puts().

I am a #defined string.

An array was initialized to me.

A pointer was initialized to me.

ray was initialized to me.

inter was initialized to me.

fputs()函数

fputs()函数puts()函数面向文件版本,两者主要的区别是:

  • fputs()函数需要第二个参数来说明要写的文件,可以使用stdout(standard output)作为参数来进行输出显示。
  • 与puts()函数不同,fputs()函数并不为输出自动添加换行符。

读取一行并把它回显在下一行,用下面的两种循环都可以办到

char line[81];

while(gets(line)) //遇到文件结尾,gets()函数就会返回空指针,循环结束

   puts(line);

char line[81];

while(fgets(line,81,stdin))

   fputs(line,stdout);

printf()函数

如同puts()函数一样,printf()函数在输出字符串的时候同样需要一个字符串地址作为参数,但是printf()函数没有puts()函数方便,但是它可以格式化多种数据类型,输出的时候也不自动添加换行符。

目录
相关文章
|
15天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
37 10
|
19天前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
56 4
|
6月前
|
NoSQL 程序员 Redis
C语言字符串的设计缺陷
C语言字符串的设计缺陷
59 1
|
2月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
3月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
101 8
|
3月前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
205 7
|
3月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
122 4
|
3月前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
4月前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
34 4
|
4月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
64 0