c++ - getline 在 C++ 中导致分段错误?
问题描述
我目前正在尝试学习 C++。我得到一个 .txt 文件,其中每行包含不同的个人数据。我想将该数据读入字符串数组。我看不出这个函数有什么问题,我之前也做过同样的事情,但由于某种原因,我收到了分段错误。
#include <string>
#include <iostream>
#include <fstream>
void readFile(std::istream&, std::string*);
int lineCount(std::istream&);
int main(){
std::ifstream inFile("input.txt");
int numLines = lineCount(inFile);
std::string data[numLines];
inFile.close();
inFile.open("input.txt");
readFile(inFile, data);
inFile.close();
return 0;
}
int lineCount(std::istream& inFile){
std::string line;
int numLines = 0;
while(std::getline(inFile, line)){
numLines++;
}
return numLines;
}
void readFile(std::istream& inFile, std::string *data){
int i = 0;
while(std::getline(inFile, data[i])){
std::cout << i << "\n"; //testing values
std::cout << data[i] << "\n"; //testing values
i++;
}
}
这是上述代码的输出。
//Output
//Note, these are fictional people
0
Florence,Forrest,1843 Glenview Drive,,Corpus Christi,TX,78401,10/12/1992,5/14/2012,3.215,127/11/1234,2.5,50
1
Casey,Roberta,3668 Thunder Road,,Palo Alto,CA,94306,2/13/1983,5/14/2014,2.978,95
2
Koch,Sandra,2707 Waterview Lane,Apt 302,Las Vegas,NM,87701,6/6/1972,12/14/2015,2.546,69
Segmentation fault //occurs in while condition
任何帮助,将不胜感激
解决方案
我感到恶心,我没有马上看到这一点。
int numLines = lineCount(inFile);
返回文件中正确的行数。虫子不在这里,伙计。
std::string data[numLines];
不是 kosher C++,但如果支持,将为文件中的每一行创建一个包含一个元素的数组。您的程序正在运行,因此受支持。不过,更喜欢使用Library Containers。
同时在readFile
...
while(std::getline(inFile, data[i]))
将尝试将一行读入data[i]
. 无论读取成功与否,都必须有一个data[i]
可读取的内容。不会有最后一次尝试。
逻辑走
- 读入第 1 行。成功,所以
- 读入第 2 行。成功,所以
- 读入第 3 行。成功,所以
- 读第 4 行。失败。但这并不能
getline
避免寻找data
一个string
持续繁荣(特别是表现为持续繁荣的未定义行为)的结束,因为没有一个。
正确的解决方案
int main(){
std::ifstream inFile("input.txt");
// no longer need. Vector keeps track for us
// int numLines = lineCount(inFile);
std::vector<std::string> data;
// read nothing from file. Don't need to rewind
readFile(inFile, data);
// note: files close themselves when they are destroyed.
//inFile.close();
return 0;
}
void readFile(std::istream& inFile, std::vector<std::string> & data){
int i = 0;
std::string line; // line to read into. Always there, so we don't have to worry.
while(std::getline(inFile, line)){
std::cout << i << "\n"; //testing values
std::cout << line << "\n"; //testing values
data.push_back(line); // stuff line into vector.
i++;
}
}
不允许的vector
解决方案
int main(){
std::ifstream inFile("input.txt");
int numLines = lineCount(inFile);
// legal in every C++, but prefer container may want some extra armour
// here to protect from numlines 0.
std::string * data = new std::string[numlines];
// the following is a faster way to rewind a file than closing and re-opening
inFile.clear(); // clear the EOF flag
inFile.seekg(0, ios::beg); // rewind file.
readFile(inFile, data);
inFile.close();
return 0;
}
void readFile(std::istream& inFile, std::string * data){
int i = 0;
std::string line; // same as above. line is here even if data[i] isn't
while(std::getline(inFile, line)){
std::cout << i << "\n"; //testing values
std::cout << line << "\n"; //testing values
data[i] = line; // stuff line into array. Smart compiler may realize it can move
//if not, c++11 adds a formal std::move to force it.
i++;
}
}
推荐阅读
- python - 在 python 数据框中访问前几行的最佳方法是什么?
- javascript - JavaScript 的街道地址正则表达式
- graphql - AWS Amplify 基于 db 字段值或关系的授权
- sql - sql:查询以查找带有额外列的最大计数
- python - 通过索引查找和替换 XML 属性 - Python
- python - 有没有办法将 Python 转换为 R?
- ruby-on-rails - Rails 6 无法部署到 Heroku:ModuleNotFoundError:找不到模块:错误:无法解析 '/tmp 中的 '@popperjs/core'
- postman - 从邮递员的外部json数据文件中读取值
- node.js - 如何使用 Node.js SDK 创建 Kubernetes 部署
- jsf - 如何防止 JSF 2.2 接受来自不同会话的 ViewState?