c++分割字符串

wWX336815 2017-06-30 08:59:01
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int main(void)
{
string str = "1234 5678 90 99";
const char* s = str.c_str();
int i = 0;
while(*s)
{
if(*s == ' ')
{
string a = str.substr(0,i);
cout << a.c_str() << endl;
str = s + 1;
i = 1;
}
++s;
++i;
}
}
这按空格分割字符串为什么str=s+1,执行完成后s指向的内容就变了。
...全文
340 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2017-07-01
  • 打赏
  • 举报
回复
引用 4 楼 wWX336815 的回复:
[quote=引用 3 楼 paschen 的回复:] s+1就是向前移动一个字符 楼主可以单步跟踪程序运行,观察每一步变量的变化情况
VS的结果太诧异了: [/quote] 因为你修改了str的值,而s指向是是str中字符串的首地址,所以s也会变
开心秋水 2017-07-01
  • 打赏
  • 举报
回复
分割字符串,还是用stringstream吧
wallesyoyo 2017-06-30
  • 打赏
  • 举报
回复
引用 8 楼 wWX336815 的回复:
[quote=引用 6 楼 jianwen0529 的回复:] [quote=引用 5 楼 wWX336815 的回复:] 执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错[/quote] 开始是"1234 5678 90 99",当遇到第一个空格时s指向“ 5678 90 99”,然后str = s+1,执行完这句话后s直接指向到" 90 99", 我的问题是这样。按理说s应该不变啊,因为这时候还没有执行++s。[/quote] 因为你的s最初指向的是你最开始构建的str对象“1234 5678 90 99”的内部缓存数据的地址,而你在执行 str = s + 1的操作后,注意这个地方你给你的str对象赋值了,所以你原始的那个“1234 5678 90 99” str对象就会销毁,而指向该已销毁对象的内部缓存的指针s,当然会出现异常。
幻夢之葉 2017-06-30
  • 打赏
  • 举报
回复
引用 8 楼 wWX336815 的回复:
[quote=引用 6 楼 jianwen0529 的回复:] [quote=引用 5 楼 wWX336815 的回复:] 执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错[/quote] 开始是"1234 5678 90 99",当遇到第一个空格时s指向“ 5678 90 99”,然后str = s+1,执行完这句话后s直接指向到" 90 99", 我的问题是这样。按理说s应该不变啊,因为这时候还没有执行++s。[/quote] 原因你s是指向str的第4个字符,之后str重新赋了新的值(内存无需重新分配,如果重新分配程序就危险了) 指向位置没变,但是指向的内容变化了 每次对str进行更改对 s重新取值,s = str.c_str(); PS:c_str()是即时的,对str的任何改变都可能造成上一次c_str()的值无效
wWX336815 2017-06-30
  • 打赏
  • 举报
回复
引用 6 楼 jianwen0529 的回复:
[quote=引用 5 楼 wWX336815 的回复:] 执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错[/quote] 开始是"1234 5678 90 99",当遇到第一个空格时s指向“ 5678 90 99”,然后str = s+1,执行完这句话后s直接指向到" 90 99", 我的问题是这样。按理说s应该不变啊,因为这时候还没有执行++s。
赵4老师 2017-06-30
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
幻夢之葉 2017-06-30
  • 打赏
  • 举报
回复
引用 5 楼 wWX336815 的回复:
执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错
wWX336815 2017-06-30
  • 打赏
  • 举报
回复
执行完16行,s指向的值直接就变了,不科学啊
wWX336815 2017-06-30
  • 打赏
  • 举报
回复
引用 3 楼 paschen 的回复:
s+1就是向前移动一个字符

楼主可以单步跟踪程序运行,观察每一步变量的变化情况


VS的结果太诧异了:
paschen 版主 2017-06-30
  • 打赏
  • 举报
回复
s+1就是向前移动一个字符 楼主可以单步跟踪程序运行,观察每一步变量的变化情况
好大一个土豆 2017-06-30
  • 打赏
  • 举报
回复
建议给s开辟空间,把str.c_str()复制到这个空间 ,再进行后面的操作
好大一个土豆 2017-06-30
  • 打赏
  • 举报
回复
因为string内部有个buffer,str.c_str()只是把这个buffer的地址返回给你。执行str= s+1后,str的buffer已经变了,s只是指向buffer的地址(++s执行n次,相当于s指向buffer第n个字节处),它的内容当然也会变。
wallesyoyo 2017-06-30
  • 打赏
  • 举报
回复
引用 11 楼 wWX336815 的回复:
[quote=引用 10 楼 wanggui2015 的回复:] [quote=引用 8 楼 wWX336815 的回复:] [quote=引用 6 楼 jianwen0529 的回复:] [quote=引用 5 楼 wWX336815 的回复:] 执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错[/quote] 开始是"1234 5678 90 99",当遇到第一个空格时s指向“ 5678 90 99”,然后str = s+1,执行完这句话后s直接指向到" 90 99", 我的问题是这样。按理说s应该不变啊,因为这时候还没有执行++s。[/quote] 因为你的s最初指向的是你最开始构建的str对象“1234 5678 90 99”的内部缓存数据的地址,而你在执行 str = s + 1的操作后,注意这个地方你给你的str对象赋值了,所以你原始的那个“1234 5678 90 99” str对象就会销毁,而指向该已销毁对象的内部缓存的指针s,当然会出现异常。[/quote] 所以此时s的值就是未定义结果,野指针,这样理解对不?[/quote] 不一定额,看被赋值字符串的容量(可以通过函数capacity查看),如果赋值的字符串长度小于被赋值字符串的容量,那就没必要再重新分配内存,直接在原始的内存上存储新的字符串内容,就跟你的程序里面能看到s里面存的是新的字符串内容。如果赋值的字符串要长于被赋值字符串的容量,那就会重新分配更大容量的内存,原来的内存就会释放掉,这个时候的s就是野指针了。
wWX336815 2017-06-30
  • 打赏
  • 举报
回复
引用 10 楼 wanggui2015 的回复:
[quote=引用 8 楼 wWX336815 的回复:] [quote=引用 6 楼 jianwen0529 的回复:] [quote=引用 5 楼 wWX336815 的回复:] 执行完16行,s指向的值直接就变了,不科学啊
s最开始指向的是str内部字符缓存的首地址,之后你有 ++s,那它不断前移肯定会变化的 “5678 90 99”到达第一个空格,s的指向" 90 99"没错[/quote] 开始是"1234 5678 90 99",当遇到第一个空格时s指向“ 5678 90 99”,然后str = s+1,执行完这句话后s直接指向到" 90 99", 我的问题是这样。按理说s应该不变啊,因为这时候还没有执行++s。[/quote] 因为你的s最初指向的是你最开始构建的str对象“1234 5678 90 99”的内部缓存数据的地址,而你在执行 str = s + 1的操作后,注意这个地方你给你的str对象赋值了,所以你原始的那个“1234 5678 90 99” str对象就会销毁,而指向该已销毁对象的内部缓存的指针s,当然会出现异常。[/quote] 所以此时s的值就是未定义结果,野指针,这样理解对不?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧