You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

使用C++读取Excel记录并按Book ID筛选,解决含空格时输出异常

解决C++读取带空格的表格内容问题

我明白你遇到的麻烦了——当书名或作者名包含空格时,你的读取代码就“罢工”,只能输出一条记录。这其实是因为你用了>>运算符来读取字符串,而这个运算符默认会把空格、制表符这类空白字符当成分隔符,一旦遇到空格就停止读取,导致带空格的字段被拆成了好几部分,整个读取逻辑就乱了。

先看看你原来的代码:

#include <iostream> 
#include<fstream>
#include<string>
#include<sstream> 
using namespace std; 

int main() { 
    string name1; 
    int i=2; 
    int d1=i; 
    string name2="c++programming"; 
    string author_name1="nileshchanglani"; 

    ofstream myfile; 
    myfile.open("my excel.xls"); 
    for(i=1;i<10;i++) 
        myfile<<i<< "\t"<<name2<<"\t"<<author_name1<<endl; 
    myfile.close(); 

    myfile.open("my excel.csv"); 
    for(i=1;i<10;i++) { 
        myfile<<i<<","<<name2<<","<<author_name1<<endl; 
    } 
    myfile.close(); 

    ifstream myfile1; 
    myfile1.open("my excel.xls"); 
    int bookid; 
    string name,author_name; 

    while(myfile1 >> bookid >> name2>> author_name) 
        if(bookid==3) 
            cout<<bookid<<" "<<name2<<" "<<author_name<<endl; 

    (myfile1>>bookid>>name2>>author_name); 
    cout<<bookid<<" "<<name2<<" "<<author_name<<endl; 
} 

问题核心

>>读取字符串时,会在遇到第一个空白字符(空格、制表符、换行)时停止。比如如果书名是"C++ Programming">> name2只会读到"C++",剩下的"Programming"会被当成下一个字段(作者名),这样整个数据的对应关系就完全错了,自然只能读到第一条有效记录。

解决方案:逐行读取+按分隔符拆分字段

不管是你生成的制表符分隔文件(后缀是xls但实际是文本)还是CSV文件,都应该先逐行读取整个行内容,再把每行按对应的分隔符(制表符\t或逗号,)拆分成单个字段,这样就能正确读取带空格的内容了。

1. 处理制表符分隔的文件("my excel.xls")

修改读取部分的代码如下:

ifstream myfile1("my excel.xls");
string line;
// 逐行读取文件
while (getline(myfile1, line)) {
    stringstream ss(line);
    int bookid;
    string name2, author_name;

    // 按制表符拆分字段:先读bookid,再读书名,再读作者名
    ss >> bookid;
    // 跳过bookid后面的制表符,然后读取书名(直到下一个制表符)
    getline(ss.ignore(), name2, '\t');
    // 读取作者名(直到换行)
    getline(ss, author_name);

    // 按Book ID控制输出,比如输出ID为3的记录
    if (bookid == 3) {
        cout << bookid << " " << name2 << " " << author_name << endl;
    }
}
myfile1.close();

2. 处理CSV文件("my excel.csv")

如果要读取CSV文件,逻辑类似,只是分隔符换成逗号:

ifstream myfile2("my excel.csv");
string line;
while (getline(myfile2, line)) {
    stringstream ss(line);
    int bookid;
    string name2, author_name;
    string temp;

    // 读取bookid
    getline(ss, temp, ',');
    bookid = stoi(temp);
    // 读取书名
    getline(ss, name2, ',');
    // 读取作者名
    getline(ss, author_name);

    if (bookid == 3) {
        cout << bookid << " " << name2 << " " << author_name << endl;
    }
}
myfile2.close();

关键说明

  • getline(cin, line)会读取整行内容,直到遇到换行符,这样就能包含所有空格了。
  • stringstream用来把整行内容拆分成字段,用getline(ss, field, 分隔符)可以指定按某个字符拆分,不会被空格干扰。
  • 注意处理数据类型转换,比如CSV里的Book ID是字符串形式,需要用stoi()转成整数。

你可以把name2改成"C++ Programming"author_name1改成"Nilesh Changlani"(带空格),然后运行代码试试,就能正确读取所有带空格的记录了。

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

火山引擎 最新活动