使用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




