C++新手求助:逐行读取文本文件时动物名称显示异常问题
嘿,我仔细看了你的问题、代码还有贴出来的输出——有意思的是,你贴的当前输出和预期输出居然完全一样?不过既然你说实际运行时动物名称没正确显示,那我大概率能猜到你遇到的是C++新手常踩的指针/内存坑,来帮你梳理下:
问题背景
我是C++纯新手,现在遇到程序输出不符合预期的问题:程序能正常逐行读取Animals.txt,但动物名称(Boris、Calvin、Dusty和Eddie)本该显示在Animal Name: 之后,实际却没正确显示。
Animals.txt 文件内容
Alice:Anaconda:10323:1. Boris:Bull:23456:2. Calvin:Cat:01320:3. Dusty:Dinosaur:00001:5. Eddie:Eagle:57429:4.
我的代码
while (counter < maximumNumbersOfAnimal) { clinic.animal[counter].number = counter; cout << "Animal Number: " << clinic.animal[counter].number << endl; file.getline(animalInfo, size, ':'); clinic.animal[counter].name = animalInfo; cout << "Animal Name: " << clinic.animal[counter].name << endl; file.getline(animalInfo, size, ':'); clinic.animal[counter].type = animalInfo; cout << "Animal Type: " << clinic.animal[counter].type << endl; file.getline(animalInfo, size, ':'); clinic.animal[counter].registrationNumber = stoi(animalInfo); cout << "Animal Registration Number: " << clinic.animal[counter].registrationNumber << endl; file.getline(animalInfo, size, '.'); clinic.animal[counter].problemNumber = stoi(animalInfo); cout << "Animal Problem Number: " << clinic.animal[counter].problemNumber << endl; counter++; }
当前输出
Animal Number: 0 Animal Name: Alice Animal Type: Anaconda Animal Registration Number: 10323 Animal Problem Number: 1 Animal Number: 1 Animal Name: Boris Animal Type: Bull Animal Registration Number: 23456 Animal Problem Number: 2 Animal Number: 2 Animal Name: Calvin Animal Type: Cat Animal Registration Number: 1320 Animal Problem Number: 3 Animal Number: 3 Animal Name: Dusty Animal Type: Dinosaur Animal Registration Number: 1 Animal Problem Number: 5 Animal Number: 4 Animal Name: Eddie Animal Type: Eagle Animal Registration Number: 57429 Animal Problem Number: 4
预期输出
Animal Number: 0 Animal Name: Alice Animal Type: Anaconda Animal Registration Number: 10323 Animal Problem Number: 1 Animal Number: 1 Animal Name: Boris Animal Type: Bull Animal Registration Number: 23456 Animal Problem Number: 2 Animal Number: 2 Animal Name: Calvin Animal Type: Cat Animal Registration Number: 1320 Animal Problem Number: 3 Animal Number: 3 Animal Name: Dusty Animal Type: Dinosaur Animal Registration Number: 1 Animal Problem Number: 5 Animal Number: 4 Animal Name: Eddie Animal Type: Eagle Animal Registration Number: 57429 Animal Problem Number: 4
可能的问题与解决办法
首先,你贴的输出看起来没问题,但实际运行时名称显示异常,最常见的原因是内存/指针赋值错误,下面是具体分析和解决:
1. 动物名称的类型是char*导致的指针复用问题
如果你的clinic.animal[counter].name是char*类型,那你直接写clinic.animal[counter].name = animalInfo时,并没有把animalInfo里的字符串内容拷贝过去,只是把animalInfo的内存地址赋值给了name。而animalInfo是同一个缓冲区,每次循环都会被新的内容覆盖,最后所有动物的name都会指向同一个内存地址,显示的自然是最后一次写入的内容(比如全是Eddie)。
解决办法:
- 优先推荐把
name的类型改成std::string(C++里尽量用标准库的string代替char数组,它会自动处理内存管理和内容拷贝),这样直接赋值就没问题:// 假设你的animal结构体定义改成这样 struct Animal { int number; std::string name; std::string type; int registrationNumber; int problemNumber; }; - 如果必须用
char*,那需要手动分配足够的内存,并用strcpy拷贝内容:// 假设name是char数组,比如char name[50]; strcpy(clinic.animal[counter].name, animalInfo); // 如果是动态分配的char*,要先分配内存: clinic.animal[counter].name = new char[strlen(animalInfo) + 1]; strcpy(clinic.animal[counter].name, animalInfo); // 注意最后要记得释放内存,避免内存泄漏
2. 文件读取时的空格残留问题
你的Animals.txt里每个条目结尾是. (点加空格),当用getline(animalInfo, size, '.')读取完problemNumber后,文件指针会停在空格的位置。下一次循环的第一个getline会先读取这个空格,导致动物名称前面多了个空格(比如显示 Boris而不是Boris)。
解决办法:
在读取完problemNumber后,跳过后面的空格:
file.getline(animalInfo, size, '.'); clinic.animal[counter].problemNumber = stoi(animalInfo); cout << "Animal Problem Number: " << clinic.animal[counter].problemNumber << endl; // 跳过后续的空格,需要包含<limits>头文件 file.ignore(numeric_limits<streamsize>::max(), ' '); counter++;
3. animalInfo的缓冲区大小不足
如果size定义的太小(比如小于动物名称的长度),会导致读取的字符串被截断,显示不全。确保size足够大,比如设为1024这样的数值:
const int size = 1024; char animalInfo[size];
总结
最可能的原因是name的类型是char*,没有正确拷贝内容而是直接赋值指针。换成std::string是最省心的解决方案,能帮你避开很多C++内存管理的坑,非常适合新手。
内容的提问来源于stack exchange,提问作者user481039239

