帮我调试这个程序,弄了半天不知道为什么?

linyuansen 2008-04-23 06:07:35

#include<iostream>
using namespace std;
#define MAXSTRLEN 255

#define TRUE 1
#define FLASE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define NULL 0
typedef int SElemType;//调试前定义元素具体类型(int)

typedef struct{
char *ch;
int length;
}HString;
typedef int Status;//为HString声明别名Status
Status StrAssign (HString &T, char *chars);//字符常量赋值

Status Assign(HString &T1, HString &T2);//字符变量赋值

int StrCompare (HString &S, HString T);

int StrLength (HString S);

Status ClearString (HString &S);

Status Concat (HString &T, HString S1, HString S2);

Status SubString (HString &Sub, HString S, int pos, int len);
Status StrDelete(HString &S, int pos, int len){
HString T, Sub1, Sub2;
SubString(Sub1, S, 1, pos-1);
SubString(Sub2,S,pos+len+1,StrLength(S)-(pos+len-1));
Concat( T, Sub1, Sub2);
Assign(S, T);
return OK;
}//delete

//—————————基本操作描述——-——————————//
Status StrAssign (HString &T, char *chars){
//生成一个其值等于串常量chars的串T
if(T.ch) free(T.ch);
int i; char *c=chars;
for(i=0;*c != '\0'; ++c,++i);
if(!i){T.ch = NULL; T.length =0;}
else
{
if(!(T.ch = (char*)malloc(i * sizeof(char))))
exit(OVERFLOW);
int j;
for(j=0; j<i; j++)
T.ch[j] = chars[j];
T.length = i;
}
return OK;
}//StrAssign
Status Assign(HString &Tl, HString &Tr){
if(Tl.ch) free(Tl.ch);
int i=StrLength(Tr), j;
if(!(Tl.ch = (char*)malloc(i*sizeof(HString))))
exit(OVERFLOW);
for(j=0; j<i; j++)
Tl.ch[j] = Tr.ch[j];
Tl.length = i;
return OK;
}




int StrLength(HString S){
//返回S的元素个数,称为串的长度。
return S.length;
}//StrLength

int StrCompare(HString S, HString T){
//若S>T,则返回值>0;若S=T,则返回=0;若S<T,则返回<0
int i;
for(i=0; i<S.length && i<T.length; ++i)
if(S.ch[i] != T.ch[i]) return S.ch[i]-T.ch[i];
return S.length - T.length;
}//StrCompare

Status ClearString (HString &S){
if(S.ch) {free(S.ch); S.ch = NULL;}
S.length = 0;
return OK;
}//ClearString

Status Concat (HString &T, HString S1, HString S2){
//用T返回有S1和S2联接而成的新串。

if(T.ch) free(T.ch);
if(!(T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char))))
exit(OVERFLOW);
int i;
for(i=0;i<S1.length; i++)
T.ch[i] = S1.ch[i];
T.length = S1.length + S2.length;
for(i=0;i<S2.length;i++)
T.ch[S1.length+i] = S2.ch[i];
return OK;
}//Concat



Status SubString (HString &Sub, HString S, int pos, int len){
//用Sub返回串S的第pos个字符起长度为len的子串。
if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
return ERROR;
if(Sub.ch) free(Sub.ch);
if(!len){Sub.ch = NULL; Sub.length = 0;}

else{
Sub.ch =(char*)malloc(len*sizeof(char));
int i;
for(i=0; i<len; i++)
Sub.ch[i] =S.ch[pos-1+i];
Sub.length = len;
}
return OK;
}//SubString

int main()
{
HString T;
char chars[]="123456789";
StrAssign(T,chars);
StrDelete(T,4,3);
int i;
for(i=0; i<StrLength(T); i++)
cout<<T.ch;
cout<<endl;
return 0;
}
...全文
137 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
linyuansen 2008-04-24
  • 打赏
  • 举报
回复
谢谢大家!!
rushman 2008-04-24
  • 打赏
  • 举报
回复
/*
* 1. 在分配内存(malloc)的时候,普遍少分配一个字符。C 的字符串需要一个'\0'作为结束字符。
* 2. 在复制
* 2. C 风格的下标是从 0 开始,应该习惯这样
* 3. 尽可能把传址和引用参数声明为 const
*/
#include <iostream>
using namespace std;
#define MAXSTRLEN 255

#define TRUE 1
#define FLASE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define NULL 0
typedef int SElemType;//调试前定义元素具体类型(int)

typedef struct HSTRING{
char *ch;
int length; /* 个人认为,用来表示所分配的内存大小比记住字符串的长度更有价值 */
HSTRING():ch(NULL),length(0){} /* 初始化结构成员 */
}HString;

typedef int Status;//为HString声明别名Status

/*
* 既然是 C++ 为什么要用 StrAssign/Assign 两个名字
* 函数在命名的时候,最好有个规范,比如都是以 Str 开头
* 常量,最好明确的声明为 const
* 我建议将接口改为如下形式:
* Status StrAssign (HString &T, const char *chars);
* Status StrAssign(HString &T1, const HString &T2);
* int StrCompare (const HString &S, const HString &T);
* int StrLength (const HString S);
* Status StrClear (HString &S);
* Status StrConcat (HString &T, const HString &S1, const HString &S2);
* Status StrSubString (HString &Sub, const HString &S, int pos, int len);
*/
Status StrAssign (HString &T, const char *chars);//字符常量赋值
Status Assign(HString &T1, const HString &T2);//字符变量赋值
int StrCompare (const HString &S, const HString &T);
int StrLength (const HString &S);
Status ClearString (HString &S);
Status Concat (HString &T, const HString &S1, const HString &S2);
Status SubString (HString &Sub, const HString &S, int pos, int len);

/*
* 删除字符串中的以 pos 开始,长度为 len 的片断
*/
Status StrDelete(HString &S, int pos, int len){
HString Sub1, Sub2;
/*
* 应该习惯 C 的从 0 开始的下标
*/
SubString(Sub1, S, 0, pos);
/*
* 这里应该是弄错了吧
* SubString(Sub2, S, pos+len+1,StrLength(S)-(pos+len-1));
*/
SubString(Sub2, S, pos + len, StrLength(S)-(pos + len));
Concat( S, Sub1, Sub2);
// Assign(S, T);
return OK;
}//delete

//—————————基本操作描述——-——————————//
/*
* 参数 chars 应该声明为 const
*/
Status StrAssign (HString &T, const char *chars){
//生成一个其值等于串常量chars的串T
if(T.ch) free(T.ch);
int i;
const char *c;
/*
* 换个效率更高、更鲁棒的
* for(i=0;*c != '\0'; ++c,++i);
*/
for(c = chars; c && *c ; c++);
i = c - chars;

if(!i){
T.ch = NULL;
T.length =0;
}
else{
/*
* 既然不影响效率,为什么不用更清晰的写法
* if( !(T.ch = (char*)malloc(i * sizeof(char))) )
*/
T.ch = (char*)malloc(i * sizeof(char) + 1);
if(!T.ch)
exit(OVERFLOW);
int j;
/*
* 改为 <= 可以把结束的 '\0' 也复制过去
*/
for(j=0; j <= i; j++)
T.ch[j] = chars[j];
T.length = i;
}
return OK;
}//StrAssign

/*
* 参数 Tr 应该声明为 const
*/
Status Assign(HString &Tl, const HString &Tr){
if(Tl.ch) free(Tl.ch);
int i=StrLength(Tr), j;
/*
* 这里为什么不判断字符串长度了
*/
if(!i){
Tl.ch = NULL;
Tl.length =0;
}
else{
// if(!(Tl.ch = (char*)malloc(i*sizeof(HString))))
Tl.ch = (char*)malloc(i * sizeof(char) + 1);
if(!Tl.ch)
exit(OVERFLOW);
for(j=0; j <i; j++)
Tl.ch[j] = Tr.ch[j];
Tl.length = i;
}
return OK;
}

/*
* 这里的 S 应该是 const 的
*/
int StrLength(const HString &S){
//返回S的元素个数,称为串的长度。
return S.length;
}//StrLength

/*
* 这里的参数都应该是 const
*/
int StrCompare(const HString& S, const HString& T){
//若S>T,则返回值>0;若S=T,则返回=0;若S <T,则返回 <0
int i;
for(i=0; i < S.length && i < T.length; ++i)
if(S.ch[i] != T.ch[i]) break; // 这里 break 就好
/*
* 循环结束的条件是两个字符串发现不等,或最少有一个结束
* 而结束的字符串的当前字符为 0,可以用统一的方式返回
*/
return S.ch[i]-T.ch[i];
}//StrCompare

Status ClearString (HString &S){
if(S.ch) {free(S.ch); S.ch = NULL;}
S.length = 0;
return OK;
}//ClearString

/*
* 参数 S1/S2 应该是 const 的引用
*/
Status Concat (HString &T, const HString &S1, const HString &S2){
//用T返回有S1和S2联接而成的新串。
if(T.ch) free(T.ch);
/*
* 这种写法就不多说了,这里的另一个问题是没有判断 S1.length + S2.length 是否为 0
* if(! (T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char))) )
*
* malloc 一个 0 长度的字符串会如何?
* MSDN 说:
* If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item.
*/
if(S1.length + S2.length > 0){
T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char) + 1);
if(!(T.ch))
exit(OVERFLOW);
int i;
for(i=0;i <S1.length; i++)
T.ch[i] = S1.ch[i];
T.length = S1.length + S2.length;
for(i=0;i <S2.length;i++)
T.ch[S1.length+i] = S2.ch[i];
/*
* 没有结束字符
*/
T.ch[S1.length + i] = 0;
}else{
/*
* If the Length is Zero
*/
T.ch = NULL;
T.length = 0;
}
return OK;
}//Concat

/*
* S 也应该是 const 引用
*/
Status SubString (HString &Sub, const HString &S, int pos, int len){
//用Sub返回串S的第pos个字符起长度为len的子串。
/*
* if( pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1 )
*/
if( pos < 0 || pos > S.length || len < 0 || len > S.length-pos+1 )
return ERROR;
if(Sub.ch) free(Sub.ch);
if(!len){
Sub.ch = NULL;
Sub.length = 0;
}else{
Sub.ch =(char*)malloc(len*sizeof(char) + 1);
int i;
for(i=0; i < len; i++)
Sub.ch[i] =S.ch[pos + i];
/*
* 字符串没有结束字符 '\0'
*/
Sub.ch[i] = 0;
Sub.length = len;
}
return OK;
}//SubString

int main()
{
HString T;
char chars[]="123456789";
StrAssign(T,chars);
StrDelete(T,4,3);
int i;
for(i=0; i <StrLength(T); i++)
cout <<T.ch[i];
cout <<endl;
return 0;
}
jianqiu_li 2008-04-24
  • 打赏
  • 举报
回复
main函数里:

for(i=0; i <StrLength(T); i++)
cout << T.ch[i];
jianqiu_li 2008-04-24
  • 打赏
  • 举报
回复
Substring的参数也使用错误
jianqiu_li 2008-04-24
  • 打赏
  • 举报
回复
简单说吧,

凡是在malloc的地方都需要修改,改为:

if(!(Tl.ch = (char*)malloc((i + 1)* sizeof( char ))))
exit(OVERFLOW);
for(j=0; j <i; j++)
Tl.ch[j] = Tr.ch[j];
Tl.ch[j]= '\0';
Tl.length = i;
linyuansen 2008-04-24
  • 打赏
  • 举报
回复
哦,SORRY,我是新手,不懂。这是个串的基本操作的算法。其中的StrDelete是我们老师要我们自己编的。这个程序就是为了实现DELETE功能。这上面的算法除了StrDelete函数自己写的,其他函数都是根据书上算法写的。
heartbeast 2008-04-23
  • 打赏
  • 举报
回复
在给出大段的代码之前,我觉得最基本的是要说明这段代码是干什么的!

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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