| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2438 人关注过本帖
标题:能不能通过代码修改文件结束标志的位子呢?
只看楼主 加入收藏
libinden71
Rank: 1
等 级:新手上路
帖 子:47
专家分:0
注 册:2015-12-3
结帖率:63.64%
收藏
已结贴  问题点数:20 回复次数:7 
能不能通过代码修改文件结束标志的位子呢?
程序代码:
void fnFwrite()
{
    FILE *pf = fopen("1.txt", "rb+");
    int nEoF = EOF;

    fseek(pf, 5, SEEK_SET);

    fwrite(&nEoF, sizeof(nEoF), 1, pf);

    fclose(pf);
}

void fnFread()
{
    FILE *pf = fopen("1.txt", "rb+");
    
    char str[10] = { 0 };

    while (!feof(pf))
    {
        fread(str, sizeof(str), 1, pf);
    }

    fclose(pf);
}

//想通过写入EOF的方式 让其在读取时认为是文件结束,停止读取,可是还是自动读取到文件结束了

数据写入文件时通过操作删除文件最后部分数据,那么最后的数据就无效了,如何修改文件结束标志让其读取时认为已经到了文件末尾停止读取(不使用其他方法)。只修改文件结束标志这需要怎么做?或者怎样通过代码的方式模拟手动删除.txt文本中最后的垃圾数据。有大神知道要怎么做吗?
搜索更多相关主题的帖子: 修改 文件 结束 标志 读取 
2019-04-29 17:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:7 
既然對文件的讀和寫都是自己程序做的,那麽定義什麽標志為文件結束符是任意的,除非你的文件要供給其他程序讀寫。文件的讀寫和數據結構,都有很大的隨意性,視需求而定,不必按照常規。

不是所有文件讀寫庫函數都判斷文件結束標志的,有些會查找結束符,有些根本無視結束符,而且不同系統和平臺定義的EOF也未必一樣。

[此贴子已经被作者于2019-4-29 18:53编辑过]


授人以渔,不授人以鱼。
2019-04-29 18:48
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
一般來説,二進制讀寫的文件,是不用結束標志的,因爲文件内容的數據取值,極可能與該標志值相同,那會造成誤判。文件結束標志的使用場合,一般是文本格式的讀寫,用t打開。EOF值一般定義為-1,但在二進制數據中,這個值太常見了。使用這個標志主要顧忌的因素很多,數據長度會影響結果,不要想當然寫32位的-1進去就可以了,如果文件被64位的系統或程序讀取,它們按64位長度去讀,取出的值未必就是-1。

最高效的獲取文件長度方案,是編制文件頭,可參考BASIC的字符串機制(比C高效),或者是諸如MP3文檔的結構。

授人以渔,不授人以鱼。
2019-04-29 19:25
libinden71
Rank: 1
等 级:新手上路
帖 子:47
专家分:0
注 册:2015-12-3
收藏
得分:0 
以下是引用TonyDeng在2019-4-29 18:48:38的发言:

既然對文件的讀和寫都是自己程序做的,那麽定義什麽標志為文件結束符是任意的,除非你的文件要供給其他程序讀寫。文件的讀寫和數據結構,都有很大的隨意性,視需求而定,不必按照常規。

不是所有文件讀寫庫函數都判斷文件結束標志的,有些會查找結束符,有些根本無視結束符,而且不同系統和平臺定義的EOF也未必一樣。


哦我明白了。多谢大神。我还有点疑问,我上面这段代码 可以通过什么办法解决让feof读取到我给定位子的结束标志就停下。我在seek到指定位置输入EOF时为什么feof还是继续往下读取,而不是停止读取?如果我想他停止读取需要怎么做?
2019-04-29 19:25
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 4楼 libinden71
系統管理文件的層面,有自己判斷文件長度的方案,庫函數會使用這些方案。feof()函數調用的API,也是系統返回的結果,你自己用不到,也寫不進去。在IO庫中,有相應截斷文件長度的函數,也有多種方式判斷讀出的數據是否已超越文件尾,比如fread()函數的返回值,是成功讀取的數量,如果這個返回值小於你指定企圖讀取的量,就意味著超越文件尾了。總之,使用這些庫函數配套的方案,不要自己讀寫EOF之類的東西。

授人以渔,不授人以鱼。
2019-04-29 19:50
Mr_doge
Rank: 5Rank: 5
等 级:贵宾
威 望:10
帖 子:159
专家分:385
注 册:2018-6-28
收藏
得分:7 
文件读取是否到达文件尾由系统环境反馈,文件写入写到哪哪就是结束,同样写入也是由系统环境管理(当然确实不是无限制的),你试图自己定义实际文件尾的想法就是试图重定义系统环境的行为,是难以实现的,除非你自己写一个系统。
    但是你可以自行用程序逻辑控制你的程序的文件读写行为,比方说设定特殊标志,数据长度控制等等,但是不要试图尝试越权改变系统的实现,那和站在楼顶拆地基差不多,除非打算在无系统环境下折腾,否则应该利用系统,配合系统,而不是去试图拆地基,亦或者目的本就是为了破坏系统的工作状态才会这么做
2019-04-29 21:32
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
實際上,EOF不是存在於文件中的數據(標志),而是程序文件管理系統反饋給程序員的數據。文件的讀寫之類操作,是操作系統中文件管理模塊負責的,每個平臺和系統都有自己的一套,編程語言提供的文件管理函數庫工具,是調用外部功能實現的(所謂調用API),那些API是一整套互相配合的函數,在讀寫文件遇到觸發文件結束事件的時候,會在系統内部設置一個被稱爲“文件結束標志”的變量為特定值,一般約定這個特定值為-1,宏名EOF或FEOF,這個標志很多函數都能設置,程序員編程的時候,是在恰當的時候去檢測這個值是什麽狀態。比如說fseek()函數,其實你把position設定到SEEK_END後面也是可以的,但隨即是要你自己在使用fseek()之後主動去檢查feof()的返回值是否為真,或者直接檢查fseek()的返回值是否為零(零代表成功),否則越界了也不知道——這裏内藏的動作,是fseek()函數調用API,系統在你的文件指針越過結束位置時把内部相應變量設置了,而feof()函數就是去讀取這個標志的。

btw:操作系統約定的返回值一般是錯誤碼(ErrorCode),表示錯誤的代碼,零表示無錯誤,這與C的慣例不同。int main()的函數的返回值為零,就是操作系統級別的ErrorCode=0。C庫中一些函數,是自己的約定,經常代表真假,也表示成功失敗,但有些函數其實是直接返回操作系統約定的代碼,卻是零為成功而非失敗。這種情況,要注意鑒別。C庫中,像fopen()返回NULL(0)表示失敗,但fseek()返回0卻是成功,兩者的意義並不相同,協議也不一致,所以其實C語言是比較混亂的。

C標準庫中IO流,其實就是面向對象的,語法跟C++不同,但其思想卻的確是面向對象的(實際上面向對象不受語法限制而是思想,用C語言也可以做出類似面向對象的程序而享受其好處)。C的IO庫,效率比C++的高許多,也好用許多,這不是某些人所説的,寫C或C++就一定要全部用它們的整套,自己靈活衡量就是了。

[此贴子已经被作者于2019-4-29 21:58编辑过]


授人以渔,不授人以鱼。
2019-04-29 21:46
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:7 
没有标准函数

windows下可以用
_chsize( _fileno(FILE*类型的变量), 字节长度 );
或 _chsize_s

linux下可以用
ftruncate( fileno(FILE*类型的变量), 字节长度 )
2019-04-30 08:56
快速回复:能不能通过代码修改文件结束标志的位子呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016369 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved