C++读取含字符与数字的文件:如何识别各类字符?
解决图结构文本文件的解析问题
嘿,我完全懂你这种卡壳的感觉——手动逐个字符判断数字、符号确实太繁琐,还容易出错。其实不用绕这么大弯,C++的输入流本身就自带了结构化解析的能力,能帮你轻松搞定这个问题!
核心思路:利用输入流的自动特性
C++的ifstream(或者stringstream)会自动跳过空白字符(空格、换行、制表符这些),而且能直接把连续的数字字符转换成int类型。我们只需要顺着文件的结构,把那些大括号{}和逗号,当成分隔符来处理就行,不用手动去判断每个字符是什么。
方法一:直接用文件流逐元素读取
这种方法适合直接从文件读取,步骤很清晰:
#include <iostream> #include <fstream> #include <vector> using namespace std; int main() { ifstream myfile("graph.txt"); if (!myfile.is_open()) { cerr << "Failed to open file!" << endl; return 1; } // 读取第一行的节点总数(也就是7) int node_count; myfile >> node_count; // 初始化邻接表,每个节点对应一个空列表 vector<vector<int>> adjacency_list(node_count); char temp_char; for (int i = 0; i < node_count; ++i) { // 先读取左大括号,不用做处理,只是跳过它 myfile >> temp_char; // 此时temp_char是'{' int neighbor; // 循环读取当前节点的邻接数字,直到遇到右大括号 while (myfile >> neighbor) { adjacency_list[i].push_back(neighbor); // 读取数字后面的字符:要么是逗号,要么是右大括号 myfile >> temp_char; if (temp_char == '}') { break; // 遇到右大括号,当前节点的邻接列表读完了 } // 如果是逗号,直接跳过,继续读下一个数字 } // 如果不是最后一个节点,跳过节点之间的逗号 if (i != node_count - 1) { myfile >> temp_char; } } // 测试输出结果 for (int i = 0; i < node_count; ++i) { cout << "Node " << i + 1 << " neighbors: "; for (int num : adjacency_list[i]) { cout << num << " "; } cout << endl; } myfile.close(); return 0; }
方法二:按行读取后用stringstream解析
如果你更习惯按行读取,也可以把第二行内容读到string里,再用stringstream来解析,逻辑和上面完全一致:
#include <iostream> #include <fstream> #include <vector> #include <sstream> using namespace std; int main() { ifstream myfile("graph.txt"); if (!myfile.is_open()) { cerr << "Failed to open file!" << endl; return 1; } int node_count; myfile >> node_count; myfile.ignore(); // 跳过第一行末尾的换行符 // 读取第二行的所有内容 string line; getline(myfile, line); stringstream ss(line); vector<vector<int>> adjacency_list(node_count); char temp_char; for (int i = 0; i < node_count; ++i) { ss >> temp_char; // 读取左大括号 int neighbor; while (ss >> neighbor) { adjacency_list[i].push_back(neighbor); ss >> temp_char; if (temp_char == '}') { break; } } if (i != node_count - 1) { ss >> temp_char; // 跳过节点间的逗号 } } // 输出测试 for (int i = 0; i < node_count; ++i) { cout << "Node " << i + 1 << " neighbors: "; for (int num : adjacency_list[i]) { cout << num << " "; } cout << endl; } myfile.close(); return 0; }
为什么这个方法更简单?
- 不用手动调用
isdigit判断字符:输入流会自动识别数字并转换成int,省掉了字符转数字的麻烦 - 自动跳过空白:你不用处理空格、换行这些无关字符,流会帮你搞定
- 逻辑更贴合文件结构:顺着
{数字,数字}的结构一步步处理,代码可读性高,也不容易出错
内容的提问来源于stack exchange,提问作者Ran Lavi
相关产品推荐
相关产品推荐

