You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从TXT文件向结构体数组存储数据:代码无法运行问题排查

问题排查与修正:将TXT数据存入结构体数组的C++代码

我来帮你排查这段代码里的问题,这些都是C++文件读取和结构体使用中常见的坑:

主要问题分析

  • 命名冲突:你定义的struct time和标准库中的std::time重名了,编译器会因为无法区分而报错,建议把结构体名改成MovieTime(或其他不重复的名字)。
  • 缺少命名空间限定:string、ifstream这些类型都属于std命名空间,但你的代码没有使用using namespace std;,也没加std::前缀,编译器找不到这些类型,会报“未定义标识符”错误。
  • 输入流换行残留问题:用>>读取整数(比如yearreleased)后,输入流里会留下一个换行符,下一个getline会直接读取这个空行,导致数据读取错位,完全不符合预期。
  • 不安全的循环条件:while (!inside.eof())是错误的写法——eof()只有在读取操作失败后才会置位,这会导致最后一次循环读取无效数据,甚至重复读取。
  • 未完成的代码与越界风险:函数里的i...是未完成的代码,而且没有限制i的最大值,一旦TXT里的数据量超过结构体数组的长度,就会触发数组越界,导致程序崩溃或内存错误。
  • 冗余头文件:<string.h>是C语言的字符串头文件,C++中应该用<cstring>,而且你的代码里没用到C风格字符串的函数,完全可以删掉它。

修正后的完整代码

#include <iostream>
#include <string>
#include <fstream>

// 重命名结构体避免和std::time冲突
struct MovieTime { 
    int hours, minutes; 
};

// 结构体成员名改用小驼峰命名(可选,只是代码更易读),同时添加std::前缀
struct MovieData { 
    std::string movieName, genre, actorName1, actorName2; 
    int yearReleased, pricePerDay; 
    MovieTime duration; 
};

// 添加maxSize参数,严格控制数组访问边界
void readMovieData(MovieData* ptr, int maxSize) {
    int i = 0;
    std::ifstream inFile("movies.txt");
    
    // 循环条件改为:数组未越界 + 成功读取电影名
    while (i < maxSize && std::getline(inFile, ptr[i].movieName)) {
        // 读取发行年份,同时检查读取是否成功
        if (!(inFile >> ptr[i].yearReleased)) {
            break;
        }
        inFile.ignore(); // 跳过年份后的换行符,确保下一个getline正常工作
        
        // 读取电影类型
        if (!std::getline(inFile, ptr[i].genre)) {
            break;
        }
        
        // 读取第一位演员名
        if (!std::getline(inFile, ptr[i].actorName1)) {
            break;
        }
        
        // 读取第二位演员名
        if (!std::getline(inFile, ptr[i].actorName2)) {
            break;
        }
        
        // 读取电影时长(假设TXT中是先小时后分钟)
        if (!(inFile >> ptr[i].duration.hours >> ptr[i].duration.minutes)) {
            break;
        }
        inFile.ignore(); // 跳过时长期后的换行符
        
        // 读取单日租金
        if (!(inFile >> ptr[i].pricePerDay)) {
            break;
        }
        inFile.ignore(); // 跳过租金后的换行符
        
        i++;
    }
}

关键修正说明

  1. 命名规范:重命名time结构体,避免和标准库冲突;结构体成员名改用小驼峰,提升代码可读性。
  2. 命名空间:所有标准库类型都添加std::前缀,如果你觉得麻烦,也可以在文件开头加using namespace std;(但大型项目不推荐,容易引发其他命名冲突)。
  3. 输入流处理:每次用>>读取数值后,都用ignore()跳过残留的换行符,确保getline能正确读取整行文本。
  4. 安全循环:循环同时检查数组边界和读取操作是否成功,既避免数组越界,又不会读取无效数据。
  5. 错误检查:每个读取操作都添加失败判断,一旦某个字段读取失败就退出循环,避免错误传播导致程序异常。

内容的提问来源于stack exchange,提问作者blackpanther

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:19:10