string str = "" 是不是相当于没有初始化

YuriOU 2005-12-20 01:02:48
#include <string>
#include <iostream>
using namespace std;
--错误:
void main()
{
string aa = ""; --初始化为""
strcpy((char *)aa.c_str(),"djsfsad"); --出现错误
cout << aa << endl;
}
--正确:
void main()
{
string aa = " "; --随便初始化为空格
strcpy((char *)aa.c_str(),"djsfsad"); --正确通过
cout << aa << endl;
}

是不是string aa = "";还是没有为aa变量分配空间,而aa = " ";就有
还是函数strcpy的问题?
假如现在必须用类似strcpy这样写法(sprintf和memcpy也出现同样问题),是不是aa不能初始化为""?
...全文
1162 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
useresu 2005-12-21
  • 打赏
  • 举报
回复
这是用strcpy最基本的思路,

如果你不清楚strcpy,

最好先msdn
useresu 2005-12-21
  • 打赏
  • 举报
回复
首先数据库的字段长度一般固定

在这种情况下,一般用定长char数组是最好的选择

new和delete绝对影响效率

但是用string实现也无可后非,

但是你用string就都用string实现好了,

完全可以省去strcpy(),

偏偏你用了char *,

你用char * 也可以,

但记得strcpy之前,

要先sizeof一下"结果"的长度,

然后给feaParm[i][0]释放原来空间,重新申请足够的空间

才能strcpy



Seben 2005-12-21
  • 打赏
  • 举报
回复
已经解释过了,

(char *)r_LbasServ.str_lbasmonthlyquota.c_str()

是不对的,至少你还不适合使用这样的用法。如果我没错的话,你应该是STL的初学者,那么我的建议是,绝对不要对STL里面的函数或对象进行强制类型转换!如果你直接使用STL的函数,而compiler报错的话,就去查msdn。
Seben 2005-12-21
  • 打赏
  • 举报
回复
//防止内存泄漏,先申请空间
r_LbasServ.str_lbasmonthlyquota.resize(512);

这样确实不会内存泄漏了,不过std::string本来就考虑了内存处理,你只用string的话,是不会内存泄漏的!

问题是数据可能会溢出。

这种问题,可能某些运行侥幸结果没有错,但是一旦出现问题,调试都调试不出来。

建议你先系统学习一下STL。
YuriOU 2005-12-21
  • 打赏
  • 举报
回复
感谢楼上各位的讨论
其实我这样写的目的是为了动态实现。
//对应数据库的各个字段,可能非常多
class struct_LbasServ{
public:
string str_lbasmonthlyquota;
string str_lbasservducity;
string str_lbasservdusplineno;
string str_lbasservducustname;
string str_lbasservduaddr;
string str_lbasacctermcount;

struct_LbasServ()
{
str_lbasmonthlyquota="";
str_lbasservducity="";
str_lbasservdusplineno="";
str_lbasservducustname="";
str_lbasservduaddr="";
str_lbasacctermcount="";
}
};

void main()
{
struct_LbasServ r_LbasServ;
//防止内存泄漏,先申请空间
r_LbasServ.str_lbasmonthlyquota.resize(512);
r_LbasServ.str_lbasservducity.resize(512);
r_LbasServ.str_lbasservdusplineno.resize(512);
r_LbasServ.str_lbasservducustname.resize(512);
r_LbasServ.str_lbasservduaddr.resize(512);
r_LbasServ.str_lbasacctermcount.resize(512);
//定义成二维数据或更多维
char* feaParm[][2] = {
{(char *)r_LbasServ.str_lbasmonthlyquota.c_str() , "MONTHLY_QUOTA" },
{(char *)r_LbasServ.str_lbasservducity.c_str() , "015" },
{(char *)r_LbasServ.str_lbasservdusplineno.c_str() , "014" },
{(char *)r_LbasServ.str_lbasservducustname.c_str() , "003" },
{(char *)r_LbasServ.str_lbasservduaddr.c_str() , "002" },
{(char *)r_LbasServ.str_lbasacctermcount.c_str() , "ACC_TERM_COUNT"},
};
//伪动态处理
for(int i=0; i < sizeof(feaParm)/sizeof(char *)/2; i++){
//把feaParm[i][1])拿出来做一系列处理(步骤很多),把最后处理的值赋值给对应的feaParm[i][0]中的字段。
//各位帮忙想想能不能在这里实现给各个字段申请空间也就是resize操作
strcpy(feaParm[i][0],结果值);
}
}

由于struct_LbasServ类中的字段非常多(上面没有全部列出来),那么对各个字段做同样的处理,如果没有写成动态,程序非常庞大而且也不易查看,所有才想出这样写的,不知道各位高手还有没有别的好方法。
deping_chen 2005-12-21
  • 打赏
  • 举报
回复
string aa = ""; --初始化为""
strcpy((char *)aa.c_str(),"djsfsad"); --出现错误

不要混用C和C++字符串。
直接写string aa = "djsfsad"; 不好吗?
tyfool 2005-12-21
  • 打赏
  • 举报
回复
string aa=" ";

strcpy((char *)aa.c_str(), "asdfasdfasdf");

cout << aa << endl;
cout << aa.size() << endl;

=====================
我得到的输出是
a
1
不是asdfasdfasdf
Seben 2005-12-20
  • 打赏
  • 举报
回复
应该最多可以输出32个字符,而不是1个。
string aa = " ";
strcpy((char *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorj1");
肯定是没有问题的

但是超过32个就有问题了
----------------

cout跟size没有关系的。输出字符串的时候,cout看到的是一个char *或const char *,它会输出直到遇到'\0'。
Seben 2005-12-20
  • 打赏
  • 举报
回复
basic_string::c_str的定义为:
const E *c_str() const

STL做了它该做的事情,就是返回一个const char * (这里显然E表示char),const char * 表示的是:这个一个const,你可以读取,但是不可以赋值;

strcpy也做它该做的事情,就是把一个const char * 复制到一个char *;

你的错误在于,把aa.c_str()做了一个强制类型转换,从而违背了STL的使用规范,这可以从aa.size() == 1得到证明。

使用strcpy,必须开辟足够的内存区,正确的做法应该是:
{
char aa[BUF_SIZE] = {0}; // or aa = {"\0"}
strcpy(aa, "djsfsad");
cout << aa << endl;
}

另外:
(1)'0' 表示ASCII码的可打印字符0,实际上它的值不是0,这个可以用以下代码验证:
char ch = '0';
int ch_int = (int)ch;
cout << ch_int << endl;

'\0' 才表示真正的0值,可以这样验证
char ch = '\0';
int ch_int = (int)ch;
cout << ch_int << endl;

(2) "\0"没有太多的意义,因为双引号"abcd"的内存表示为:{'a','b','c','d','\0'},也就是说双引号会自动添加一个0值在字符串的后面。

(3) string aa = ""; aa为NULL 这个说法不对,NULL表示没有赋值的指针,NULL是一个宏,它在VC6下的定义就是0;""并不是NULL,可以参考(2)

(4) (char*)variable是一种C的类型转换模式,在C++中强烈不推荐使用;STL是基于C++的,它有它的基本思想,【用vector<char>代替string就很爽么?感觉越来越麻烦了。】这种说法也是不鼓励的。
useresu 2005-12-20
  • 打赏
  • 举报
回复


用vector<char>代替string就很爽么?感觉越来越麻烦了。
//////////////////////////
扫了一眼,就看到这个了,

vector代替sting ,不可取,

sting 还是有其特殊性的.

重申上述观点:
指针操作错误并不一定就出错

但是你是在制造错误的隐患

useresu 2005-12-20
  • 打赏
  • 举报
回复
没看楼上们的回复 ,

所以我以下说的可能是废话

但是楼主所谓的正确通过

只是一种侥幸

不能作为正确的理由,

你这样只是对字符串指针赋了值,

然后侥幸没有出错误,

这种做法绝对是错误的

一定要先申请足够的空间
huangjianmin 2005-12-20
  • 打赏
  • 举报
回复
在你们讨论完成前做个记号,各位该说的能说的都差不多了
YuriOU 2005-12-20
  • 打赏
  • 举报
回复
没别的好方法,只能先进行空间分配,比如预存入500个字符,
那么:
void main()
{
string aa = "";
aa.resize(500/16+1);
strcpy((char *)aa.c_str(),"djsfsadafdfdsfadsfdsffeasdfdwquiorjkasdjfoisudfoid...");
cout << aa << endl;
}
all4u 2005-12-20
  • 打赏
  • 举报
回复
用vector<char>代替string就很爽么?感觉越来越麻烦了。
v41dugu 2005-12-20
  • 打赏
  • 举报
回复
好象是12个吧。。。呵呵 也不是很清楚 不过这个不重要 你知道string str="";str里有一个元素是'\0'就对了
dragonzxh 2005-12-20
  • 打赏
  • 举报
回复
STL对string的优化吧。。。。先构造16的字符串,超过则再构造,不超过就 16个。好像是的。乱说的
rbofnjtu 2005-12-20
  • 打赏
  • 举报
回复
当strDestination没有足够的空间容纳strSource时,看来结果是undefined的。我又试了几次,不同的情况下结果都不一样,没什么规律。总之,当strDestination没有足够的空间容纳strSource时,相当于对未合法分配的内存空间进行操作(有点类似于野指针导致的后果),strcpy是不对所操作的空间进行检查的,所以,不要那么用才是最好的办法^_^
另外刚才debug的时候发现一个有趣的现象,当字符串的长度不超过15时,是存放在string对象的_Bx._Buf中的,这个_Buf的长度只有16。当字符串的长度在16以上时,是存放在string._Bx._Ptr指向的一个地址空间的,不知道为什么是这样,有什么特别的原因吗?哪位高人给解说一下?另外我用的是.net环境编译的,这样的现象是VC特有还是C++的标准(有人说VC自带的STL比较烂)
sinall 2005-12-20
  • 打赏
  • 举报
回复
套用新东方老罗的一句话:用错误推理得出正确答案。

把你的aa.size()打出来看看。

为什么输出会对呢?是因为strcpy做了它该做的事情——这才是问题真正可怕的地方。
strcpy不管三七二十一,只管拷贝……
YuriOU 2005-12-20
  • 打赏
  • 举报
回复
应该最多可以输出32个字符,而不是1个。
string aa = " ";
strcpy((char *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorj1");
肯定是没有问题的

但是超过32个就有问题了
YuriOU 2005-12-20
  • 打赏
  • 举报
回复
但是我在vc6下
string aa = " ";
strcpy((char *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorjkasdjfoisudfoid...");

按你所说的应该是输出d字符
实际上输出了djsfsadafdfdsfadsfdsffewquiorjkasdjfoisudfoid...
加载更多回复(18)

64,646

社区成员

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

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