C++ strings

85 篇文章 0 订阅

在C++ 语言中, 诸如 “Hello, word!” 这样的string literals, 在内存中是以 a sequence of characters 的形式保存的。 换句话说, 一个string, 就相当于一个character array(字符数组)。 考虑如下程序:

#include <iostream>
using namespace std;

int main() {
   char helloWorld[] = {'H', 'e', 'l', 'l', 'o', ',', ' ',
                       'w', 'o', 'r', 'l', 'd', '\0'};
   const char* hello2 = "Hello, world2"; // string, 自动加 \0 //再次修改于2015.2.7, 加上const修饰
   char hello3[] = "hello, word3";

   cout << helloWorld << endl;
   cout << hello2 << endl;

   cout << hello3;

   return 0;
}
运行结果如下:


 注意, 第一个helloWord[], 最后一‘\0’(称为the null character)结束,表明该string 的结束。

第二个hello2, 不用写‘\0’以表示string的结束, 因为compiler会自动插入一个null character('\0')。


除了可以直接处理一个string的individual character, 我们也可以通过调用C++ 相应的库函数处理string。 只需要将这些库函数#include 进我们的程序中, 就可以直接使用。 常见的library 及其功能如下:


下面给出一个使用cctype 库的例子:

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

int main() {
   char messyString[] = "t6H0I9s6.is.99a9.STRING";

   char current = messyString[0];
   for (int i = 0; current != '\0'; current = messyString[++i]) {
      if(isalpha(current))
         cout << (char) (isupper(current)? tolower(current) : current);
      else if(ispunct(current))
         cout << " ";
   }
   cout << endl;
   return 0;
}

上面的程序使用了cctype library 中的如下函数:

isalpaha():判断传递进来的字符是否为字母, 若是, 返回true, 否则false

isupper():判断传递进来的字符是否为大写字母, 若是, 返回true, 否则false

tolower():将传进来的大写字母转换为小写字母

ispunct():判断传递进来的字符是否为标点符号, 若是, 返回true, 否则false


下面是一个使用cstring library 的程序:

<pre name="code" class="cpp">#include <iostream>
#include <cstring>
using namespace std;

int main() {
   char fragment1[] = "I am a s";
   char fragment2[] ="tring!";
   char fragment3[20];
   char finalString[20] = ""; //partially initialized(with just null character)
<pre code_snippet_id="409240" snippet_file_name="blog_20140628_4_9867172" name="code" class="cpp">fragment3
strcpy(fragment3, fragment1);// 将fragment1 的内容拷贝到fragment3, 将fragment3原来的所有的内容覆盖掉 
strcat(finalString, fragment3); //concanate fragment3 ont0 finalString strcat(finalString, fragment2);
 cout << finalString; 
return 0;
}


 
 执行结果如下(编译完成时, 会提示使用更安全的strcpy_s, strcat_s等函数, 只是警告), Anyway , 直接运行(不过使用编译器推荐的函数, 更好) : 

One thing to note:

当A 是数组, cout << A << endl;的两种不同的表示情况:

(1)A 是存放的是character的时候, 输出的是真个存放空间下的字符串。

(2)当A是整数型数组的时候, 输出的是该整数数组的地址:

#include <iostream>

using namespace std;

int main() {
    int A[] = {1, 2, 3};
    cout << A << endl;

    return 0;
}



原因见stack overflow:



I'm using C++ to understand how exactly pointers work. I have this piece of code using arrays, which I'm using just to understand how the equivalent works with pointers.

int main() {    
    int arr[10] = {1,2,3};    
    char arr2[10] = {'c','i','a','o','\0'};
    cout << arr << endl;
    cout << arr2 << endl;
}

However when I run this, arr outputs the address of the first element of the array of ints (as expected) but arr2 doesn't output the address of the first element of the array of chars; it actually prints "ciao".

What is it that I'm missing or that I haven't learned yet about this?

share | edit
 

4 Answers

up vote 19 down vote accepted

It's the operator<< that is overloaded for const void* and for const char*. Your char array is converted to const char* and passed to that overload, because it fits better than to const void*. The int array, however, is converted to const void* and passed to that version. The version of operator<< taking const void* just outputs the address. The version taking the const char*actually treats it like a C-string and outputs every character until the terminating null character. If you don't want that, convert your char array to const void* explicitly when passing it to operator<<:

cout << static_cast<const void*>(arr2) << endl;
另外, 对于char* 的指针,声明的时候初始化, 一般使用NULL对其初始化, 虽然char* p = "hello"; 也是声明加初始化同时完成, p 指向的地址是编译器 string constant 分配的地址。 对于int*p = 0; *p = 2; 这句话是打错特错的。 因为编译器不会为数字分配地址。 给指针初始化的地址为0, 0 是非法地址。 我们可以通过指针间接与地址打交道, 但是却不能直接与地址打交道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值