打开文件和判断文件结束的问题

程序心声 2013-03-26 03:06:50
大家好,我有一个读文件方面的问题,挺奇怪的。希望大家帮帮忙。代码如下:
CFileDialog dlg(TRUE, ".txt", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "文本文件(*.txt)|*.txt|所有文件 (*.*)|*.*||");
CString m_path;
if(dlg.DoModal()==IDOK)
{
CString m_FilePath = dlg.GetPathName();
m_path = m_FilePath; //将文件的路径放入m_path
UpdateData(FALSE);
}
CFile File;
File.Open(m_path,CFile::modeRead);
......能够打开文件,也能够读取文件内容,没有问题
但我不想用CFile来做,我想用fstream 或ifstream来完成,如果我把以上两行换成fstream 或ifstream来打开文件,就再也成功不了了
以下是替换的代码:
fstream infile;
infile.open(m_path);
if(!infile.is_open()) //总是失败,就没成功过
{
Message("失败");
}else
{
string str;
while(!infile.eof()) //判断流中保存的是不是终结符
{
infile >> str;
if(infile.fail())
{
break;
}else
Message(str);
}
}
infile.close();
infile.clear();

1. 我发现,问题好像是在两个函数的参数上,dlg.GetPathName()所获取的文件路径,格式如:C:\X\XX\XXX.txt,用File.Open(m_path,CFile::modeRead)可以成功,如果我换成infile.open(“C:\\X\\XX\\XXX.txt”)就可以成功,我用m_path就不能成功,为什么啊,难道就是单斜杠和双斜杠的差别,为什么前一个用单斜杠就可以呢?什么时候用双斜杠呢?我又怎么把获取的路径改成双斜杠呢,有什么函数可以转换,我不能用手改吧。这是第一个问题。
2. 我通过fstream来读文件的时候,通过infile.eof()来判断文件是否结束,但是我的测试文件,每次到最后一个数据的时候,最后一个数据还没读出来,就结束了。但我把最后一个数据后,再加几个空格,最后一个数据就能读取了,这是怎么回事,我怎么才能保证最后一个数据一定能读上呢?
我的分数不多,但请大家帮帮忙,谢谢了,回答的时候,请说清楚是第几个问题,不只是说怎么改,把原因也最好解答一下,我在线等,请大家踊跃发言,我要的很急啊,现在就卡在这了,感谢啊。
...全文
177 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2013-03-28
  • 打赏
  • 举报
回复
1,
infile.open(m_path);//does "CString->char const*" do the right thing?
2, check stream state after every reading operator

infile >> str;
if(infile)
{
  //balbala
}
else
{
  //balabala
}
bravery36 2013-03-28
  • 打赏
  • 举报
回复
fstream对中文路径的支持让人发指,要么是setlocale,要么是用wchar_t来输入路径。我宁可用fopen系列的,省事且功能也足够了。
www_adintr_com 2013-03-28
  • 打赏
  • 举报
回复
在程序的开始位置加一个函数调用: setlocale(LC_ALL, "Chinese-simplified");
ForestDB 2013-03-27
  • 打赏
  • 举报
回复
http://xboyhjm.iteye.com/blog/889600
ForestDB 2013-03-27
  • 打赏
  • 举报
回复
学会搜索是必须的。
程序心声 2013-03-27
  • 打赏
  • 举报
回复
谢谢3楼的,不过既然说了,就应该说彻底,把CString类型如何转换成const char *类型直接写出来嘛,反正都到嘴边了,临门一脚啊。不过还是谢谢,还有,什么时候用双斜杠,没说啊。 那么第二个问题呢,怎么没人回答啊。
程序心声 2013-03-27
  • 打赏
  • 举报
回复
谢谢5楼的回答,可能FILE *有很多好处,但是fstream也有它的优点,而且,我现在是想怎么解决,是一种技术上的提升,我想,肯定有办法的吧,否则,也不可能还有人用fstream很久,也不可能作用文件读写其中的一种专门方法了。遇到问题不能总绕着走,我就想知道,用fstream应该怎么处理,也是知识的积累吧,希望你能帮忙解答。
程序心声 2013-03-27
  • 打赏
  • 举报
回复
谢谢“adlay”,首先谢谢你的答复,你把两个问题都回答了。第二个问题的答案,我得调一调,才能确定你说的是否能解决问题。不过你第一点说对了,用fstream确实不支持中文,当我的路径中含有中文的时候,文件就读不出来了,我还正想着怎么解决呢。对了,你说有中文的话需要setlocal,能说具体点吗,怎么用啊,没用过setlocal,这是个函数还是啥。
赵4老师 2013-03-27
  • 打赏
  • 举报
回复
摒弃fstream; 使用FILE * 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
www_adintr_com 2013-03-27
  • 打赏
  • 举报
回复
1. CString 转成 char* 可以用它的 GetBuffer() 方法. 当你要在字符串里写一个 \ 的时候, 你要写成 "\\". 因为 C 把 \ 当做转义字符了. fstream 打不开, 确认下你的路径名中是否有中文. 有中文的话你要 setlocal 之后 fstream 才能打开. 2. 这样读看你能显示完不: while(infile >> str) //判断流中保存的是不是终结符 { Message(str); }
程序心声 2013-03-27
  • 打赏
  • 举报
回复
又是“zhao4zhong1”,先不论你说的,光你回复了这么多的内容,我谢谢你。 对于你说的第一条,学习忠告,我理解,我基本也是这么做的,虽不敢说自己做的很好,但想法和你没有太大差别。 其次,你说要调试,我调试了,单步,结果还有一个字节没读出来,while(!infile.eof())硬生生的就跳出来了,我也是没办法,才发了帖子,否则,我也不会在惜时如金的时候,还来发帖。 最后,虽然你还是没有帮我直接回答问题,但我谢谢你的关注,希望你及所有人,能继续的关注我,并给予我帮助,如果能直接解决问题的那就更好了。
赵4老师 2013-03-27
  • 打赏
  • 举报
回复
Q2. 我通过fstream来读文件的时候,通过infile.eof()来判断文件是否结束,但是我的测试文件,每次到最后一个数据的时候,最后一个数据还没读出来,就结束了。但我把最后一个数据后,再加几个空格,最后一个数据就能读取了,这是怎么回事,我怎么才能保证最后一个数据一定能读上呢? A2. 单步调试和设断点调试是程序员必须掌握的技能之一。 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 有时处理带汉字的文件名或文件内容需要#include <locale.h> setlocale(LC_ALL,"chs"); 不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) { if (条件1) break; //... if (条件2) continue; //... if (条件3) return; //... } 因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。 典型如: 下面两段的语义都是当文件未结束时读字符 whlie (!feof(f)) { a=fgetc(f); //... b=fgetc(f);//可能此时已经feof了! //... } 而这样写就没有问题: whlie (1) { a=fgetc(f); if (feof(f)) break; //... b=fgetc(f); if (feof(f)) break; //... } 类似的例子还可以举很多。
赵4老师 2013-03-27
  • 打赏
  • 举报
回复
对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
程序心声 2013-03-27
  • 打赏
  • 举报
回复
又是“ForestDB”,谢谢你的回复。怎么没有人回答第二个问题啊,这个很难吗?不至于吧。
ForestDB 2013-03-26
  • 打赏
  • 举报
回复
m_path是CString类型,但是fstream需要的是const char *类型,明显两个类型不一样。
程序心声 2013-03-26
  • 打赏
  • 举报
回复
上面的,我没明白你啥意思,你是要说明fstream下open函数的用法吗,请你说清楚啊,还要让人猜。 照你这么说,我还要学fs.open("fstream.txt", ios::in);每次把文件名直接写进去啊,请你看清楚,我的文件是要让用户自己选的,我不可能让他永远打开一个固定的文件,请你回答问题之前先想一想好不。 还有,不要把MSDN随便就原样COPY上来,COPY谁不会啊。
chuachua66 2013-03-26
  • 打赏
  • 举报
回复
MSDN上不是这么写的么:
int main(int argc, char **argv)
{
    fstream fs("fstream.txt", ios::in | ios::out | ios::trunc);
    if (!fs.bad())
    {
        // Write to the file.
        fs << "Writing to a basic_fstream object..." << endl;
        fs.close();

        // Dump the contents of the file to cout.
        fs.open("fstream.txt", ios::in);
        cout << fs.rdbuf();
        fs.close();
    }
}

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧