C++使用ifstream提取数据后输出字符串与数字粘连问题求解
问题根源排查
你遇到的字符串和数字粘连问题,和ifstream读取数据的逻辑完全无关——>>运算符默认会自动跳过所有空白分隔符(空格、换行、制表符),对字符串、整数、浮点数的类型转换是自动完成的,你实际读入的各字段数据本身是完全正确的。
真正的问题出在对输出格式控制规则的误解上:C++标准库的setw()(来自<iomanip>头文件)有一个非常容易踩坑的特性:
setw(n)仅对紧跟在它后面的第一个输出项生效,不会影响后续所有输出;如果不对输出项设置宽度,相邻两个输出内容会直接首尾相接,没有任何间隔。
你原来的输出代码写反了宽度设置的位置:
// 错误的写法:宽度设置错位 cout << left << trees[i].getTreeName() // 输出树名,完全没预留宽度,输出完直接接后面的内容 << setw(25) << trees[i].getHeight() // 仅给高度值设置了25字符的宽度
这就导致树名字符串输出完成后,没有任何间隔,紧接着输出高度值,自然就形成了armeniaca39、prunusPersica23这种粘连效果;而因为高度值被设置了25字符宽度,数字后面会补一大串空格,这和你实际看到的输出表现完全吻合。
修正方案
按照每个输出字段的顺序,把setw(宽度值)放在对应输出项的前面,给每一列都预留足够的显示宽度。因为你已经开启了left左对齐模式,每个字段会在自己的宽度范围内靠左排列,剩余位置自动用空格填充,不会再出现粘连。
修正后的输出循环代码如下:
for (i = 0; i < rows; i++) { cout << left << setw(20) << trees[i].getTreeName() // 给树名留20字符宽度 << setw(10) << trees[i].getHeight() // 给高度值留10字符宽度 << setw(10) << trees[i].getLeafSize() // 给叶片大小留10字符宽度 << setw(10) << trees[i].getFlower() // 给花的特征留10字符宽度 << setw(10) << trees[i].getFruit() // 给水果名称留10字符宽度 << trees[i].getFruitColor() // 最后一列不需要预留宽度 << endl; }
额外优化建议
- 删掉代码里定义但从未使用的
char whitespace = ' ';变量,属于冗余代码 - 文件读取环节增加流状态判断,避免文件打开失败时程序进入无意义的死循环:
// 替换原来的读取循环 treeData.open("trees.txt"); int i = 0; // 增加treeData有效性判断,文件读取失败/读到文件末尾时自动退出 while (i < rows && treeData) { treeData >> name_tree >> height_tree >> size_leaf >> flower_tree >> fruit_tree >> color_fruit; trees[i].setTreeName(name_tree); trees[i].setHeight(height_tree); trees[i].setLeafSize(size_leaf); trees[i].setFlower(flower_tree); trees[i].setFruit(fruit_tree); trees[i].setFruitColor(color_fruit); i++; } // 操作完成后及时关闭文件流 treeData.close();
内容的提问来源于stack exchange,提问作者PanchamBro
相关产品推荐
相关产品推荐

