solid ZOUBINSTIHGB
facet normal 3.368912e-002 1.910605e-001 9.810000e-001
outer loop
vertex 1.026845e+000 2.821233e+000 5.241527e+001
vertex 3.676627e-016 3.002293e+000 5.241527e+001
vertex 0.000000e+000 -4.898425e-016 5.300000e+001
endloop
endfacet
facet normal -3.368912e-002 1.910605e-001 9.810000e-001
outer loop
vertex -1.026845e+000 2.821233e+000 5.241527e+001
vertex 0.000000e+000 -4.898425e-016 5.300000e+001
vertex 3.676627e-016 3.002293e+000 5.241527e+001
endloop
endfacet............
.....................
.....................从这样一个文件中读取数值,用于创建二叉树的各结点值。
class CRWSTL
{
public:
typedef struct VertexList//点二叉树的结点结构
{
double vertexlist[3];//此点的三维坐标
struct VertexList *Rchild;//右指针
struct VertexList *Lchild;//左指针
}VertexList,* VerList;
void PreVer(VertexList *Ver);//前序遍历
void CreateVer(VertexList *Ver);//创建结点
void WriteSTL();//遍历二叉树,将结点值写入文件
void ReadSTL();//读文件取数值,创建二叉树
CRWSTL();
virtual ~CRWSTL();
protected:
CString strcov;
CString str;
char ch[60];
char *token;
CStdioFile file,fw;//文件对象
VertexList *Ver;//结构指针
double te;
};
char seps[]=" ";
void CRWSTL::ReadSTL()
{
char* pFileName = "E:\\Temp\\dd\\Debug\\test.STL";
if( !file.Open( pFileName, CFile::modeReadWrite
| CFile::typeText ) )
{
AfxMessageBox("打开文件失败");
return;
}
while(file.ReadString(ch,59)!=NULL)//循环读取文件行
{
CreateVer(Ver);//创建结点
}
Ver=NULL;
file.Close();
AfxMessageBox("读取完毕");
}
void CRWSTL::WriteSTL()
{
char* pFileName = "E:\\Temp\\dd\\Debug\\w.STL";
if( !fw.Open( pFileName, CFile::modeCreate |CFile::modeReadWrite
| CFile::typeText ) )
{
AfxMessageBox("打开文件失败");
return;
}
VertexList * ver;
PreVer(ver);//前序遍历
fw.Close();
}
//创建结点
void CRWSTL::CreateVer(VertexList *Ver)
{
file.ReadString(ch,59);
token = strtok(ch,seps);//seps为空格,将空格前的字符取出到token
if(!strcmp(token,"vertex"))//判断每行的第一个字符串是不
//是vertex,如果是,将其后面的
//三个数值取出用于创建结点
{
Ver=new VertexList;//访问操作为生成根结点
for(int v=0;v<3;v++)
{
Ver->vertexlist[v]=atof(token=strtok(NULL,seps));//结点取值
}
CreateVer(Ver->Lchild);//递归建左子树
CreateVer(Ver->Rchild);//递归建右子树
}
}
//前序遍历
void CRWSTL::PreVer(VertexList *Ver)
{
if(Ver!=NULL)
{
for(int v=0;v<3;v++)
{
te=Ver->vertexlist[v];//程序运行至此出错
strcov.Format("%s",te);
fw.WriteString(strcov);
}
PreVer(Ver->Lchild);
PreVer(Ver->Rchild);
}
}
程序在运行至前序遍历函数void CRWSTL::PreVer(VertexList *Ver)
的te=Ver->vertexlist[v];时出错,是怎么回事
// RWSTL.cpp: implementation of the CRWSTL class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RWSTL.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
char seps[]=" ";
CRWSTL::CRWSTL()
{
}
CRWSTL::~CRWSTL()
{
}
void CRWSTL::ReadSTL()
{
char* pFileName = "test.STL";
if( !file.Open( pFileName, CFile::modeReadWrite
| CFile::typeText ) )
{
AfxMessageBox("打开文件失败");
return;
}
while(file.ReadString(ch,59)!=NULL)//循环读取文件行
{
CreateVer(Ver);//创建结点注意Ver最后成了尾结点,不知是不是一的用意
}
你的问题就在这里了,因为你的最后一个节点的左右节点指针成了野指针,你却没有把它置为NULL导致最后第
归无法判断指针是不是NULL,继续访问了页指针造成访问违规了,下面是我添加的代码?编译运行通过
================================================================
Ver->Lchild=NULL;//尾结点左子树置无
Ver->Rchild=NULL;//尾结点右子树置无
================================================================
file.Close();
AfxMessageBox("读取完毕");
}
void CRWSTL::WriteSTL()
{
char* pFileName = "w.STL";
if( !fw.Open( pFileName, CFile::modeCreate |CFile::modeReadWrite
| CFile::typeText ) )
{
AfxMessageBox("打开文件失败");
return;
}
PreVer(Ver);//前序遍历
fw.Close();
}
//创建结点
VerList CRWSTL::CreateVer(VerList Ver1)
{
file.ReadString(ch,59);
token = strtok(ch,seps);//seps为空格,将空格前的字符取出到token
if(!strcmp(token,"vertex"))//判断每行的第一个字符串是不是vertex,如果是,将其后面
的三个数值取出用于创建结点
{
Ver1=new VertexList;//访问操作为生成根结点
for(int v=0;v<3;v++)
{
Ver1->vertexlist[v]=atof(token=strtok(NULL,seps));//结点取值
}
//下面的代码我稍微改了一下
Ver1->Lchild=CreateVer(Ver1->Lchild);//递归建左子树
Ver1->Rchild=CreateVer(Ver1->Rchild);//递归建右子树
}
return Ver1;
}
//前序遍历
void CRWSTL::PreVer(VerList Ver1)
{
if(Ver1==NULL)
AfxMessageBox("nothing");
else
{
for(int v=0;v<3;v++)
{
te=Ver1->vertexlist[v];//程序运行至此出错
strcov.Format("%d",te);
fw.WriteString(strcov);
}
PreVer(Ver1->Lchild);
PreVer(Ver1->Rchild);
}
}
//程序在运行至前序遍历函数void CRWSTL::PreVer(VertexList *Ver)
//的te=Ver->vertexlist[v];时出错,
第一个错误注视里面我已经说了,也是你最关键的问题 解决了。
第二个错误就是你的程序你面有些函数里直接用了类里面的全局变量Ver,我感觉上会造成许多的错误,而且这
样写代码太不科学了,所以我把它换成了Ver1,用Ver的时候传给函数里面的ver1,不只是不是你原来的意思,
比如这段代码的意思就变了
VerList CRWSTL::CreateVer(VerList Ver1)
{
file.ReadString(ch,59);
token = strtok(ch,seps);//seps为空格,将空格前的字符取出到token
if(!strcmp(token,"vertex"))//判断每行的第一个字符串是不是vertex,如果是,将其后面
的三个数值取出用于创建结点
{
Ver1=new VertexList;//访问操作为生成根结点
for(int v=0;v<3;v++)
{
Ver1->vertexlist[v]=atof(token=strtok(NULL,seps));//结点取值
}
Ver1->Lchild=CreateVer(Ver1->Lchild);//递归建左子树
Ver1->Rchild=CreateVer(Ver1->Rchild);//递归建右子树
}
return Ver1;
}
原来用ver的时候返回后ver是尾结点或者说是上一个节点的右结点,改了以后返回后ver是头
结点,,现在还不知道你到底什么意思,我觉得应该反回头结点才对,
第三
while(file.ReadString(ch,59)!=NULL)//循环读取文件行
{
CreateVer(Ver);//创建结点注意Ver最后成了尾结点,不知是不是一的用意
}
你的这段代码我觉得有问题你要的ver是什么?为什么关注这个,因为你的PreVer要用到这个,你这样写最终返
回的是尾结点(右结点),我觉得他应该是头结点,但我还没有帮你改,看你自己的想法了,还有就是while循环
里面用了file.ReadString(ch,59)!=NULL但CreateVer里面又用了file.ReadString(ch,59)!=NULL,有没有什么
逻辑错误?
第四
在写之前一定要先读才可一,
第五
无效指针本来是不应该当作参数传递的,你的代码也真是的。诶!!!
可能我给你该了代码运行上没有什么问题,但结果可能会有逻辑错误,
最后给我加一百分吧,累死我了,问题不难,但打字太累了哈哈