C语言中的字符串

C语言利用字符串常量和字符串变量来便捷地处理字符串。

字符串常量

字符串常量是使用一对双引号括起来的字符序列,包括可打印字符和转义字符。在字符串字面量中使用数字转义序列时要小心,因为不同的编译器可能把转移序列分解为不同的字符集合。

对于无法在单独一行内放置的字符串常量 ,通过把第一行用字符\结尾,C语言允许在下一行延续该字符串常量。使用这种方法的缺陷是字符串常量必须从第二行的起始位置继续,这样势必会破坏程序的缩进结构。还有一种更加有效地方法,将一条长的字符串常量分割为多条字符串常量放置在多行中,因为C语言标准规定编译器会将仅用空白字符分割的多条字符串常量合并为单独一条字符串。

C语言将字符串常量作为字符数组存储,当C语言编译器遇到长度为n的字符串常量时,它会为其分配长度为n+1的内存空间,在字符串常量所有字符的末尾额外存放一个空字符\0。编译器将字符串常量看成是char *类型的指针,因此可以在任何使用char *的地方使用字符串常量,比较特殊的用法是可以为字符串常量添加下标,访问特定字符。

不要修改字符串常量。

/**************************************
 * string_literal.c                   *
 *                                    *
 * C语言的字符串常量                  *
 **************************************/

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

int main()
{
  printf("1: This is a very very very very very very long string literal!\n");

  printf("2: This is a \
very very very very very very \
long string literal!\n");

  printf("3: This is a "
         "very very very very very very "
         "long string literal!\n");

  size_t length = strlen("4: This is a very very very very very very \
long string literal!\n");

  size_t i = 0;
  for (; i < length; i++)
  {
    printf("%c", "4: This is a very very very very very very \
long string literal!\n"[i]);
  }

  return 0;
}

string_literal

字符串变量

C语言没有提供单独的字符串类型的变量,而是使用一维的字符数组存储字符串,该字符数组总是以空字符\0结尾的。因此在声明存放字符串的字符数组时,要保证字符串数组的长度总比字符串的长度多一个字符。用宏定义字符长度,用对宏加1的长度创建字符数组是常用的方法。

字符串变量的初始化就是一维字符数组的初始化,可以使用字符串常量来初始化一维字符数组。

char 数组名[] = 字符串字面量;

编译器将字符串常量看作是是最后一个字符为\0的一个初始化序列。如果字符串常量的长度比数组的长度短,则数组余下的元素都为空字符,如果字符串字面量的长度与数组长度相等,则将字符串字面量的字符赋值给数组,忽略\0字符,字符数组不再是字符串,如果字符串字面量的长度比数组长度长,则访问越界,是非法的。与声明一般数组一样,声明一维数组时也可以不指定长度,由编译器根据初始化的字符串字符量自动计算长度。

/**************************************
 * string_var_init.c                  *
 *                                    *
 * C语言中字符串变量的初始化          *
 **************************************/

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

#define STR_LEN 30

int main()
{
  char hi[STR_LEN + 1] = "1: Hello World";
  printf("%s\n", hi);

  char hi2[] = "2: Hello World";
  printf("%s\n", hi2);

  printf("\"3: Hello World\"的长度为%u\n", (unsigned)strlen("3: Hello World"));

  char hi3[14] = "3: Hello World";
  int i = 0;
  for (; i < 14; i++)
  {
    printf("%c", hi3[i]);
  }
  printf("\n");

  return 0;
}

字符串初始化

字符串的读写

可以利用printf函数使用转换说明符%s输出字符串,printf会逐个输出字符串中的字符直到遇到空字符为止。除了printf函数,C语言中还有另一个输出字符串的函数puts,它的原型为:

int puts(const char *str)

puts函数只有一个参数,就是需要显示的字符串的指针。在输出完字符串后,puts函数会额外输出一个换行符,移到下一输出行的开始处。

可以利用scanf函数使用转换说明符%s读入字符串,scanf会跳过空白字符,从第一个非空白字符开始读入并将字符存储在字符串中直到遇到空字符为止,然后在读入字符的末尾添加一个空字符。由于输入的是字符串指针,不需要再使用取地址符。除了scanf函数,C语言还提供了另一个字符串输入函数gets,gets函数的原型为:

char * gets ( char * str );

gets函数不会在开始读字符串之前跳过空白字符,遇到换行符之外的空白字符也不会停止,直到遇到换行符。gets函数不会将换行符存储在字符串中,而是将其替换为一个空字符。getsputs函数较为简单,因此速度比printfscanf会更快。由于安全性考虑,gets函数已不建议使用,更安全的版本是fgets

还可以利用getchar函数逐个字符读取字符串,可以更大程度地控制字符串的读入策略。

/*************************************
 * string_print.c                    *
 *                                   *
 * C语言中字符串的输入和输出         *
 *************************************/

#include <stdio.h>

#define STR_LEN 30

int main()
{
  char str[STR_LEN + 1] = "";
  puts("请输入你的名称: ");
  scanf("%s", str);
  printf("你好,%s\n", str);
  printf("请输入你的国籍:\n");
  getchar();
  gets(str);
  printf("你是%s人\n", str);

  puts("输入你的ID,输入Tab结束");
  char ch;
  int i = 0;
  char id[STR_LEN + 1];
  do
  {
   ch = getchar();
   if (ch == 'q')
     break;
   else
     id[i] = ch;
   i++;
  }while(i <= STR_LEN);

  id[i] = '\0';
  puts(id);

  return 0;
}

字符串输入输出

字符串的访问

由于字符串实际上是一个一维数组,因此可以用下标的方式访问,也可以用指针的方式访问。

/**************************************
 * string_char_visit.c                *
 *                                    *
 * C语言访问字符串                    *
 **************************************/

#include <stdio.h>

#define STR_LEN 60

int main()
{
  char hi[STR_LEN] = "Good good study, day day up!";

  int i = 0;
  for (; i < STR_LEN; i++)
  {
    if (hi[i] == '\0')
      break;
    putchar(hi[i]);
  }
  printf("\n");

  char *p = hi;
  for(; p < hi + STR_LEN; p++)
  {
    if (*p == '\0')
      break;

    putchar(*p);
  }
  puts("");

  return 0;
}

字符串访问

常用的C语言处理函数

C语言将字符串看作字符数组来处理,同数组的限制一样,没有提供支持字符串的复制、比较、合并和选择等操作的运算符。但C语言提供了丰富的函数库,支持这些操作。这些函数的原型存放在string.h文件中,使用这些函数前需要利用预处理命令包含该文件

#include <string.h>
strcpy函数

strcpy是字符串复制函数,原型为

char *strcpy(char *s1, const char *s2);

该函数将s2指向的字符串复制给s1指向的字符串,该函数依次将s2中的字符复制到s1中直到遇到s2的一个空字符为止。要确保s2传入的字符长度不能超过s1的长度。返回值为目标字符串的指针s1

strcat函数

strcat是字符串拼接函数,原型为:

char *strcat(char *s1, const char *s2);

strcat函数将s2指向的字符串的内容追加到s1指向的字符串的末尾,并返回目标字符串的指针s1。要确保追加后的字符串的长度不超过s1的长度。

strcmp函数

strcmp函数用以字符串比较,其原型为

int strcmp(const char *s1, const char *s2);

strcmp依据字典中单词的编排顺序比较大小,返回负数表示s1指向的字符串小于s2指向的字符串, 返回0表示s1等于s2,返回正数表示s1大于s2

strlen函数

strlen函数用以计算字符串长度,其原型为:

size_t strlen(const char *s);

strlen函数返回第一个空字符前的字符个数。

/**************************************
 * string_function.c                  *
 *                                    *
 * C语言函数库中的字符串处理函数      *
 **************************************/

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

#define STR_LEN 60

int main()
{
  char str1[STR_LEN] = "";
  char str2[STR_LEN] = "Hello World";

  strcpy(str1, str2);
  puts(str1);

  char str3[STR_LEN] = ", Another World!";
  strcat(str1, str3);
  puts(str1);

  int comp = strcmp(str1, str3);
  printf("str1和str3的比较结果为%d\n", comp);

  printf("str1的字符长度为%u\n", (unsigned)strlen(str1));

  return 0;
}

几个字符串处理函数

字符串数组

可以通过创建二维的字符数组的方式来存储字符串数组,但是以这样的方式存储的话,对于不能够填满的字符都将用空字符填充,造成空间的浪费。因此可以利用指向字符串指针的方式存储数据,每个数组元素都是一个字符串指针,这样就不必限定每个数组元素的字符串的长度。

程序在运行时有时需要提供额外的信息,这些信息被成为程序参数或命令行信息。为了访问这些信息,必须把主函数定义为两个参数的形式:

int main(int argc, char *argv[])

argc是命令行参数的数量,包括程序名本身,argv是指向命令行参数的指针数组,存放表示命令行参数的字符串。

/****************************************
 *  string_commandlinepara.c            *
 *                                      *
 * C语言的字符串数组存储命令行参数      *
 ****************************************/

#include <stdio.h>

int main(int argc, char *argv[])
{
  int i = 0;
  for (i = 0; i < argc; i++)
    printf("%d: %s\n", i+1, argv[i]);

  return 0;
}

命令行参数

参考文献

  1. K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
  2. http://www.cplusplus.com/reference/
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值