C和C++中字符串操作

C和C++中字符串操作

string变量(对象)就是面向对象编程中的“对象”的一个很好的例子。下面我们比较一下C语言与C++语言中处理字符串的不同方式,对面向过程和面向对象编程有一个感性认识。

C语言中有很多字符串操作函数,常见的有:

  • 字符串复制:char *strcpy(char *s1, const char *s2);
  • 求字符串长度:size_t strlen(const char *s);
  • 字符串拼接:char *strcat(char *s1, const char *s2);
  • 字符串比较:int strcmp(const char *s1, const char *s2);

以求字符串长度为例,我们来看看用C语言的方式怎样处理:

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

int main()
{
    char one_line[20];
    int length;
    gets(one_line); // 像C++中的getline那样,可以输入含有空格的字符串
    length = strlen(one_line);
    printf("the length of \"%s\" is %d\n", one_line, length);
    return 0;
}

C++中字符串保存在string类型的变量(对象)中,而与上述字符串操作对应的操作:

  • 字符串复制:string& assign (const string& str);
  • 求字符串长度:size_t length() const;
  • 字符串拼接:string& append (const string& str);
  • 字符串比较:int compare (const string& str) const;

与C语言的那些函数最大的不同的是,上述函数是属于string变量自身的函数,调用方式是变量名.函数名(...);

以求字符串长度为例,我们来看看用C++语言的方式怎样处理:

#include <iostream>
#include <string>

int main()
{
    std::string one_line;
    int length;
    getline(std::cin, one_line);
    length = one_line.length(); // length是one_line的一个函数(方法)
    std::cout << "the length of \"" << one_line << "\" is " << length << std::endl;
    return 0;
}

尽管上述的两个例子很小,但是也反映了面向过程和面向对象编程的一个重大区别:面向过程程序中变量由变量“外部”函数进行处理,而面向对象程序中处理某个变量的方式往往是调用属于其“内部”的函数,这种变量(对象)内的函数也叫成员函数。

可能有人会问,不都是达到我们使用字符串的目的吗,这种区别有更大的意义吗?

现实中的事物(以C语言中的结构体变量或者C++中的对象来表达的居多)很多都有自己的行为(函数)。如果将这些行为划归于这个事物自身,而不是事物的外部,更加有利于程序员在现实问题和程序之间建立对应。面向过程中的关注点更加偏重于处理变量的那些“动态”过程,而面向对象中关注点更加偏重于含有一定成员函数的“静态”对象。这更有利于码农们进行程序设计和程序调试。含有函数的变量(对象)起到了某种支点的作用。

这种函数归属于变量的特性反映了面向对象三大特性中的封装特性,封装性也是另两大特性,即继承和多态的基础。

一个例子

下面的程序称为姓名装框程序,你可以输入姓名,程序输出问候语,并且将问候语恰好放在由’*’号组成的框中。

姓名装框程序

思考一下,利用C语言的方式处理这个程序应该如何下手?

…10分钟过去了

可能有些同学首先想到进行各种字符串输出,直到最终输出成图片中的样子。这里我推荐对应各行输出内容建立一个字符数组,先将输出的字符串保存到字符数组中,最后一起输出它们。这样程序逻辑相对清晰,而且输出的第5行和第1行相同,第4行和第2行相同,我们只要建立保存前3行字符串的3个字符数组即可。各位可以思考下用户输入的姓名保存到单独的字符数组后,先“组装”哪行数组呢。

下面给出部分代码

#include <iostream>
using namespace std;

// 确保输入姓名不超过20个字节
#define MAX_NAME_LENGTH 20
// 确保每行最长不超过40个字节
#define MAX_LINE_LENGTH 40

int main()
{
    char line1[MAX_LINE_LENGTH  + 1] = {0};
    char line2[MAX_LINE_LENGTH + 1] = {0};
    char line3[MAX_LINE_LENGTH + 1] = {"* 你好,"};
    char name[MAX_NAME_LENGTH + 1] = {0};
    int line_width;

    printf("请输入姓名:");
    gets(name);
    strcat(line3, name);
    strcat(line3, "! *");
    line_width = strlen(line3);

    // 开始组装其它行
    ...
    // 结束组装其它行

    printf("%s\n", line1);
    printf("%s\n", line2);
    printf("%s\n", line3);
    printf("%s\n", line2);
    printf("%s\n", line1);

    return 0;
}

注意,在组装各行字符串的时候,小心结束字符’\0’。

C语言的程序编写完成,可以再用C++中string对象来解决这个问题。string对象可以自动管理保存字符串的大小,使用它我们就不需要考虑大小问题了。

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string line1, line2, line3(""* 你好,""), name;
    int line_width;

    cout << "请输入姓名:";
    cin >> name;
    line3.append(name); // 或者 line3 += name;
    line3.append("! *"); // 或者 line3 += "! *";
    line_width = line3.length();

    // 开始组装其它行
    ...
    // 结束组装其它行

    cout << line1 << endl;
    cout << line2 << endl;
    cout << line3 << endl;
    cout << line2 << endl;
    cout << line1 << endl;

    return 0;
}

可以猜到string line3(“”* 你好,”“); 是定义string变量,并且以括号里的字符串初始化它。

以上就是以C++方式编写的程序。可以看到,C++中的变量“自带”方法,这个就是封装的体现。同时也可以看到,尽管使用了面向对象的类,但是各体来说处理流程还是过程式的。面向对象只是一种代码组织方式,在实际编程过程中面向过程和面向对象都是需要的。

上一篇:字符串和基本输入输出

下一篇:引用和函数重载

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值