在C++下面读入string类型,存入vector中非常的简单。在C语言下面读入string倒是很简单,但是要存入指针数组中貌似费了很大的劲都不行。C还是四年之前看过,对于C下面的字符串一直很恐惧,今天下定决心,要好好研究一下
**********************************************************************************************
首先来分析字符数组和字符指针:
输出结果如下:
字符型数组和字符型指针都是可以表示字符串的,它们的结尾处为'\0';
一直在说 数组名实际上是数组的首地址值 ,从这点可以看出scanf输出字符串的原理。因为字符型指针名传递的肯定是地址,所以scanf(“%s”)的原理肯定是找到所传递的地址处,挨个的输出地址中的字符,直到碰到'\0',认为字符串结束了。
下面可以做个小试验:
输出的结果如下:
实际上char型的数组和指针没有什么特殊的性质。它们的特殊之处仅仅在于,当碰到%s,它们表示为string时,系统知道'\0'表示结束。
**********************************************************************************************
再来分析指针数组:
弄明白上面的一点,这个的结果也很容易理解,如下:
感觉关键就在于"%s"这个选项上,它的机制就是找地址(注意是地址),然后输出,碰到'\0'结束。
**********************************************************************************************
为了将字符串存入字符型的指针数组中,首先先搞定将字符串存入字符指针中:
结果显而易见:
这里的原理和第一部分一样, %s的机理是从地址入手。
**********************************************************************************************
下面是关键了,将用户输入的字符串存入指针数组中。先模仿C++的思路,写一个显而易见的版本。
结果如下:
可以看第48行这里是一个指针之间的赋值, 实际上传递的是地址值,所以字符指针数组中的每个值都是tmp的地址值,所以最后结果是一样的 。
正确的方法应该是,改变charPointerArray中每一个元素所指的地址中的内容(字符串):
---------------------------------------------------------------------------------------------
使用strcmp可以对字符串的内容赋值,但是将地48行改成如下的形式,会报错:
会出现内存引用的错误:
可以思考一下这里是为什么?举个更加简单的例子来看:
这里也是会报内存引用出错。strcpy的作用机理是将huan[]的字符复制到chen中,直到'\0'为止。这里使用了一个未初始化的字符指针,编译器不知道该指针指向哪里,实际上就是一个NULL,对它的应用所以会报错。
下面可以做一个小测试,使用new为它分配一个地址,然后再来运行:
下面是运行的结果:
这里可以看出,只要不是NULL就可以了(废话了,NULL的引用必然出错。。。
)
所以之前会出现内存的引用出错,完全是因为使用了NULL,chen指向不知道的地址,strcpy也不知道往哪里赋值。
---------------------------------------------------------------------------------------------总结前面得到的两点,接下来就可以解决最开始提出来的问题:
(1) 字符指针还是指针,它显的特殊,仅仅是因为%s的内部机制;
(2)对指针的操作前提是指针必须不是NULL。
所以想要将char* c的值存入char* sp[]中,必须单独的为每个sp[n]先分配内存(C用malloc或C++用new),下面是最后的版本:
哈哈,最后的结果如下:
**********************************************************************************************
一晚上就搞了这么一个问题,不过很值得。终于完全弄懂C语言下的字符串了,再也不需要使用stringstream来回避它,哈哈~~~很享受这种慢慢的分析问题到最后解决问题的过程,nice~~~虽然原因现在看起来很2B~~~最后再声明一遍哈:
(1) 字符指针还是指针,它显的特殊,仅仅是因为%s的内部机制;
(2)对指针的操作前提是指针必须不是NULL。
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
**********************************************************************************************
首先来分析字符数组和字符指针:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/bf0f3e220733b45ae1268964010822c8.jpeg)
输出结果如下:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/f6dc700bcd35b4102d53dc4e41bdcdec.jpeg)
字符型数组和字符型指针都是可以表示字符串的,它们的结尾处为'\0';
一直在说 数组名实际上是数组的首地址值 ,从这点可以看出scanf输出字符串的原理。因为字符型指针名传递的肯定是地址,所以scanf(“%s”)的原理肯定是找到所传递的地址处,挨个的输出地址中的字符,直到碰到'\0',认为字符串结束了。
下面可以做个小试验:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/a00ac97ab0f12b5097730fd64962701b.jpeg)
输出的结果如下:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/a38ec6668b86ffd6207b8195801a743a.jpeg)
实际上char型的数组和指针没有什么特殊的性质。它们的特殊之处仅仅在于,当碰到%s,它们表示为string时,系统知道'\0'表示结束。
**********************************************************************************************
再来分析指针数组:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/943eecad3b91f2a08702e287827f337b.jpeg)
弄明白上面的一点,这个的结果也很容易理解,如下:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/c515479d6c5305343002ac41bd702edf.jpeg)
感觉关键就在于"%s"这个选项上,它的机制就是找地址(注意是地址),然后输出,碰到'\0'结束。
**********************************************************************************************
为了将字符串存入字符型的指针数组中,首先先搞定将字符串存入字符指针中:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/95e8e0a60ae4e1480e80bee226dff468.jpeg)
结果显而易见:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/be63b8dec3e70da5cdc2757d79e0223a.jpeg)
这里的原理和第一部分一样, %s的机理是从地址入手。
**********************************************************************************************
下面是关键了,将用户输入的字符串存入指针数组中。先模仿C++的思路,写一个显而易见的版本。
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/27e1997244814e31c3bcfe7d39479a9c.jpeg)
结果如下:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/b760fbe133a4274114d34e54b8903ff8.jpeg)
可以看第48行这里是一个指针之间的赋值, 实际上传递的是地址值,所以字符指针数组中的每个值都是tmp的地址值,所以最后结果是一样的 。
正确的方法应该是,改变charPointerArray中每一个元素所指的地址中的内容(字符串):
---------------------------------------------------------------------------------------------
使用strcmp可以对字符串的内容赋值,但是将地48行改成如下的形式,会报错:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/1ea655e6ca512266775a7677363ac345.jpeg)
会出现内存引用的错误:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/c50c51f421459a06832c3436b16091b0.jpeg)
可以思考一下这里是为什么?举个更加简单的例子来看:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/b792ba78c3f9354188b816641cc19d2b.jpeg)
这里也是会报内存引用出错。strcpy的作用机理是将huan[]的字符复制到chen中,直到'\0'为止。这里使用了一个未初始化的字符指针,编译器不知道该指针指向哪里,实际上就是一个NULL,对它的应用所以会报错。
下面可以做一个小测试,使用new为它分配一个地址,然后再来运行:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/5754f09335b3efedc3564604f586d539.jpeg)
下面是运行的结果:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/9e3a394c41a16e42e1e581473cac52d2.jpeg)
这里可以看出,只要不是NULL就可以了(废话了,NULL的引用必然出错。。。
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/676ebda4729556d2ae74a2569eb85a7a.gif)
所以之前会出现内存的引用出错,完全是因为使用了NULL,chen指向不知道的地址,strcpy也不知道往哪里赋值。
---------------------------------------------------------------------------------------------总结前面得到的两点,接下来就可以解决最开始提出来的问题:
(1) 字符指针还是指针,它显的特殊,仅仅是因为%s的内部机制;
(2)对指针的操作前提是指针必须不是NULL。
所以想要将char* c的值存入char* sp[]中,必须单独的为每个sp[n]先分配内存(C用malloc或C++用new),下面是最后的版本:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/38c5d706c8e6d7f9a3474f35cf4b91dd.jpeg)
哈哈,最后的结果如下:
![C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[]) C语言:将输入的字符串(char* <wbr>cp)存入字符指针数组(char <wbr>* <wbr>spa[])](https://i-blog.csdnimg.cn/blog_migrate/a4903a31986bb174d62ee91e1d85adfd.jpeg)
**********************************************************************************************
(1) 字符指针还是指针,它显的特殊,仅仅是因为%s的内部机制;
(2)对指针的操作前提是指针必须不是NULL。