初冀 2023-04-25 23:17 采纳率: 61%
浏览 9

数据结构从文件获取数据报错文件格式有误


//从文件创建树
int CreateTreeFromFile(char fileName[], pTree& T)
{
    FILE* pFile;                     //定义顺序表的文件指针
    char str[1000];                  //存放读出一行文本的字符串
    char strTemp[10];                //判断是否注释行

    int i = 0, j = 0;
    errno_t err = fopen_s(&pFile,fileName, "r");
    if (!pFile)
    {
        cout<<"错误:文件打开失败."<<endl ;
        return false;
    }

    while (fgets(str, 1000, pFile) != NULL)  //跳过空行和注释行
    {

        strLTrim(str);                  //删除字符串左边空格
        if (str[0] == '\n')               //空行,继续读取下一行
            continue;

        strncpy_s(strTemp, str, 2);         //将str中的前两个字符拷贝到strTemp中
        if (strstr(strTemp, "//") != NULL)  //跳过注释行
            continue;
        else                            //非注释行、非空行,跳出循环
            break;
    }

    //循环结束,str中应该已经是文件标识,判断文件格式
    if (strstr(str, "Tree or Forest") == NULL)
    {
        cout<<"错误:打开的文件格式错误!"<<endl;
        fclose(pFile);                  //关闭文件
        return false;
    }


    //读取结点数据,到str。跳过空行
    while (fgets(str, 1000, pFile) != NULL)
    {
        strLTrim(str);                  //删除字符串左边空格
        if (str[0] == '\n')               //空行,继续读取下一行
            continue;

        strncpy_s(strTemp, str, 2);
        if (strstr(strTemp, "//") != NULL)  //注释行,跳过,继续读取下一行
            continue;
        else                            //非空行,也非注释行,即图的顶点元素行
            break;
    }

    //结点数据存入树的结点数组
    char* ptr = NULL;
    char* token = strtok_s(str, " ",&ptr);
    int nNum = 0;
    while (token != NULL)
    {
        T.node[nNum].data = *token;
        T.node[nNum].parent = -1;       //父结点指针初始化为-1

        token = strtok_s(NULL, " ",&ptr);

        nNum++;
    }

    //循环读取边(父子队)数据
    int nP;  //父结点数组下标
    int nC;  //子结点数组下标

    elementType Nf, Ns; //父子结点对的两个结点
    while (fgets(str, 1000, pFile) != NULL)
    {
        //删除字符串左边空格
        strLTrim(str);
        if (str[0] == '\n')  //空行,继续读取下一行
            continue;

        strncpy_s(strTemp, str, 2);
        if (strstr(strTemp, "//") != NULL)  //注释行,跳过,继续读取下一行
            continue;

        char* token = strtok_s(str, " ",&ptr);  //以空格为分隔符,分割一行数据,写入邻接矩阵

        if (token == NULL)  //分割为空串,失败退出
        {
            cout << "错误:读取树的边数据失败!" << endl;
            fclose(pFile); //关闭文件
            return false;
        }
        Nf = *token;  //获取父结点

        token = strtok_s(NULL, " ",&ptr);  //读取下一个子串,即子结点
        if (token == NULL)  //分割为空串,失败退出
        {
            cout<<"错误:读取树的边数据失败!"<<endl;
            fclose(pFile); //关闭文件
            return false;
        }

        Ns = *token;  //获取边的第二个结点(子结点)
            //取得父结点下标
        for (nP = 0; nP < nNum; nP++)
        {
            if (T.node[nP].data == Nf)  //从顶点列表找到第一个顶点的编号
                break;
        }
        //获取子结点的数组下标
        for (nC = 0; nC < nNum; nC++)
        {
            if (T.node[nC].data == Ns)  //从顶点列表找到第二个顶点的编号
                break;
        }

        T.node[nC].parent = nP;        //nC的父结点的下标为nP
    }

    T.n = nNum;  //树的结点数,即顶点数组的实际大小

    fclose(pFile); //关闭文件
    return true;
}
//二叉树数据文件
//二叉树标识--BinaryTree,无此标识将判定文件格式不对。
//每行表示二叉树中的一个结点。由3项组成:
     //第一项是结点元素值;
     //第二项表示此结点有无左子树,其中:1--有左子树,0--无左子树;
     //第三项表示此结点有无右子树,其中:1--有右子树,0--无右子树。
//结点次序(从上到下)必须严格按照先序遍历次序排列。
//文件扩展名没有限制,程序只根据标识“BinaryTree”判定是否二叉树数据文件。
//文件中可以有空行。
//文件可以有注释行,注释行必须以“//”开始,且注释行必须是单独的行,不能混杂在标识行、数据行中
//此二叉树有10个结点

BinaryTree
A  1  1
B  1  1
C  0  0
D  1  0
E  0  0
F  1  1
G  0  1
H  0  0
I  1  0
J  0  0

img


想问一下为什么打开文件格式错误啊,我的从文件读取数据的函数还有这个数据文件都是teacher给的代码,只是把几个C语言的东西换成了C++,为什么说格式错误呢

  • 写回答

2条回答 默认 最新

  • 于扶摇 2023-04-25 23:38
    关注
    
    # 从文件创建树  
    def CreateTreeFromFile(fileName, pTree):  
        # 打开文件  
        pFile = open(fileName, 'r')  
        if not pFile:  
            return False  
      
        # 读取文件内容  
        pText = pFile.read()  
        pFile.close()  
      
        # 解析文件内容  
        pToken = pText.split()  
        pNode = {}  
        pNode['label'] = pToken[0]  
        pNode['children'] = []  
      
        # 遍历文件内容,创建节点  
        for i in range(1, len(pText)):  
            if pText[i] == '(':  
                pNode['children'].append({'label': pToken[i+1], 'children': []})  
                pNode = pNode['children'][-1]  
            elif pText[i] == ')':  
                pNode['children'].pop()  
                pNode = pNode['children'][-1]  
            else:  
                # 判断是否注释行  
                if i > 0 and pText[i] == '/' and pText[i-1] == '/':  
                    continue  
                # 判断是否非空行  
                if i > 0 and pText[i] != ' ':  
                    continue  
                # 如果是注释行,跳过  
                if pText[i] == '/' and pText[i-1] == '/':  
                    continue  
                # 如果是非空行,跳过  
                if pText[i] != ' ':  
                    continue  
      
        # 处理节点,返回节点对象  
        return pNode  
      
    # 测试代码  
    tree = CreateTreeFromFile('data.txt', pTree)  
    print(tree)
    
    评论

报告相同问题?

问题事件

  • 创建了问题 4月25日

悬赏问题

  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,
  • ¥15 angular项目错误