C++中的fstream的getLine()方法以及存有的疑问

关于助教在上课的时候用于读取文件内容的getLine方法,

在今天经过一个小程序试验得到这样的结果,

但是至今不懂得为什么,先记录下来之后再去找答案

1.读取文件test中行的内容,代码是下所示

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

int main(){
	char name[]="test.txt";
	fstream fs(name,ios::in);
	char content[10];
	if(fs.is_open()){
		while(!fs.eof()){//此处为错误
			fs.getline(content,10);
			cout<<content<<endl;
		}
	}
	return 0;
}

而test.txt中的内容为

1234567
12345678902345
1234567
123456667666666666666
1231111111111111111111

!!!!!!!!!!!!!!问题:

其中内容从第2行开始就超过了10个字符的长度,然后从读取完第二次后,发现进行读取时,content中的内容没有变化,也就是说读取失败?这是为什么?而且这样while循环条件 !fs.eof()一直是成立的,为什么?

2.下面是同一个程序,将content的长度改变,getLine()方法的参数也改变成25,代码如下

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

int main(){
	char name[]="test.txt";
	fstream fs(name,ios::in);
	char content[25];
	if(fs.is_open()){
		while(!fs.eof()){
			fs.getline(content,25);
			cout<<content<<endl;
		}
	}
	return 0;
}


结果:

此处content内容能够正确打印,且正确退出循环

3.在写一个小程序的时候还出现过这个问题:后面发现char content[20],而fs.getLine(content,30);然后出现了这个...后面想想个那个函数的调用压栈有关系吧,就是可能把返回地址给覆盖了?【好吧,真的不懂。。。以后过来修改解释】


总结:

虽然还是有问题不会,但是还是有些收获的。

在使用fstream的getLine()方法时,参数一定要大于一行储存的最长字符长度,否则会失败;若是getLine的参数大于字符个数,那么程序运行读取content完毕后,会在数组的末尾自动加上'\0';而且根据助教的写法,while成立的条件为fs.getLine(content,25),感觉起来安全很多,至少不会因为读取一次错误造成一直在循环...


ps:要是哪位看到了这个,能够解释我的疑问的话,欢迎指教。。。3Q


以下是一个简单的实现,假设窗口类名为CMyDialog,控件ID为IDC_EDIT_NAME, IDC_EDIT_ACCOUNT, IDC_EDIT_PASSWORD, IDC_EDIT_IDCARD, IDC_EDIT_BALANCE,按钮ID为IDC_BUTTON_QUERY,文本文件名为info.txt。 首先需要在初始化对话框时读取文本文件并存储信息到vector: ```cpp #include <vector> #include <fstream> #include <sstream> class CMyDialog : public CDialog { private: struct Info { std::string name; std::string account; std::string password; std::string idcard; double balance; }; std::vector<Info> m_infos; public: CMyDialog(CWnd* pParent = nullptr) : CDialog(IDD_MY_DIALOG, pParent) { std::ifstream file("info.txt"); if (file.is_open()) { std::string line; while (std::getline(file, line)) { std::istringstream iss(line); std::string name, account, password, idcard; double balance; std::getline(iss, name, ','); std::getline(iss, account, ','); std::getline(iss, password, ','); std::getline(iss, idcard, ','); iss >> balance; m_infos.push_back({ name, account, password, idcard, balance }); } file.close(); } } // ... }; ``` 接着在按钮的OnClick事件查找匹配的信息并将其显示到控件: ```cpp class CMyDialog : public CDialog { // ... public: afx_msg void OnBnClickedButtonQuery() { CString name, account, password, idcard, balance; GetDlgItemText(IDC_EDIT_NAME, name); GetDlgItemText(IDC_EDIT_ACCOUNT, account); GetDlgItemText(IDC_EDIT_PASSWORD, password); GetDlgItemText(IDC_EDIT_IDCARD, idcard); GetDlgItemText(IDC_EDIT_BALANCE, balance); for (auto& info : m_infos) { if ((!name || info.name == LPCTSTR(name)) && (!account || info.account == LPCTSTR(account)) && (!password || info.password == LPCTSTR(password)) && (!idcard || info.idcard == LPCTSTR(idcard)) && (!balance || info.balance == _ttof(balance))) { SetDlgItemText(IDC_EDIT_NAME, info.name.c_str()); SetDlgItemText(IDC_EDIT_ACCOUNT, info.account.c_str()); SetDlgItemText(IDC_EDIT_PASSWORD, info.password.c_str()); SetDlgItemText(IDC_EDIT_IDCARD, info.idcard.c_str()); SetDlgItemText(IDC_EDIT_BALANCE, std::to_wstring(info.balance).c_str()); return; } } AfxMessageBox(_T("未找到匹配信息")); } }; ``` 注意这里使用了CString和std::wstring之间的转换,以及字符串到数字的转换。同时也需要判断控件是否为空,如果为空则表示用户不想限制这个条件。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值