| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1174 人关注过本帖, 1 人收藏
标题:关于最简单的C语言文件操作的问题!
只看楼主 加入收藏
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:205
专家分:35
注 册:2014-10-9
收藏
得分:0 
回复 9楼 TonyDeng
那版主可否帮小妹编写一个程序。把桌面一个文件a里的内容以二进制(0-1)代码的形式输出发到桌面的文件b~文件a和文件b都是已经建好的哦~

既然还有不甘心
就还没到放弃的时候~
2015-09-26 17:52
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:205
专家分:35
注 册:2014-10-9
收藏
得分:0 
回复 9楼 TonyDeng
程序是模仿谭浩强书上搞的

既然还有不甘心
就还没到放弃的时候~
2015-09-26 17:52
S140131022
Rank: 2
来 自:重庆邮电大学
等 级:论坛游民
帖 子:205
专家分:35
注 册:2014-10-9
收藏
得分:0 
回复 10楼 诸葛欧阳
老师周一要要啊。。。我这两天还在加班~~  版主能帮忙写一下不?

既然还有不甘心
就还没到放弃的时候~
2015-09-26 17:53
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
1.你知道桌面的絕對路徑嗎?
2.我用vc,寫了你會轉成自己所用編譯器能通過的形式嗎?

我不知道老師為什麼要你在桌面上搞名堂。

[ 本帖最后由 TonyDeng 于 2015-9-26 18:05 编辑 ]

授人以渔,不授人以鱼。
2015-09-26 18:00
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用边小白在2015-9-26 18:20:00的发言:

把编译后的exe文件放在桌面上运行,是不是就默认在桌面路径操作文件了?


這樣可以,不這樣也可以。關鍵是如果沒有搜獲到目標目錄的絕對路徑,就必須使當前目錄是目標目錄。

授人以渔,不授人以鱼。
2015-09-26 18:22
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你用下面給的函數就可以了:
程序代码:
#include <stdio.h>
#include <stdlib.h>

#define __VC__

/*
功能:複製文件
參數:targetFilename -- 目標文件名,可帶絕對或相對路徑
      sourceFilename -- 源文件名,可帶絕對或相對路徑
返回:如果操作成功,返回零,否則返回系統錯誤碼(非零),查閱此錯誤碼信息包含致錯原因
*/
int Copy_File(const char* targetFilename, const char* sourceFilename)
{
    FILE* source;            // 源文件句柄
    FILE* target;            // 目標文件句柄
    errno_t errorCode = 0;    // 錯誤碼
    int ch;                    // 文件讀寫的單個字節

#ifdef __VC__
    errorCode = fopen_s(&source, sourceFilename, "rb");        // 以二進制讀模式打開源文件
    if (errorCode != 0)
    {
        return errorCode;
    }
#else
    source = fopen(sourceFilename, "rb");
    if (source == NULL)
    {
        return !0;
    }
#endif
#ifdef __VC__
    errorCode = fopen_s(&target, targetFilename, "wb");        // 以二進制寫模式創建目標文件
    if (errorCode != 0)
    {
        fclose(source);
        return errorCode;
    }
#else
    target = fopen(targetFilename, "wb");
    if (target == NULL)
    {
        fclose(source);
        return !0;
    }
#endif

    // 複製
    for (ch = fgetc(source); ch != EOF; ch = fgetc(source))
    {
        fputc(ch, target);
    }

    fclose(target);            // 關閉目標文件,系統刷寫數據流至磁盤文件
    fclose(source);            // 關閉源文件

    return errorCode;
}

int main(int argc, char* argv[])
{
    Copy_File("D:\\test_new.prg", "D:\\test.prg");
    return EXIT_SUCCESS;
}


這是逐個字節複製的版本,當文件比較小時,由於系統有緩衝區,這樣速度是很快的,祗要文件比較龐大時,才會有緩慢現象,具體到多大規模出現問題,應由實測決定,祗要不是無法忍受,不必考慮別的方案。

非vc+6以上編譯器,以及其他編譯器,取消前面的宏即可,沿用舊版本函數。

[ 本帖最后由 TonyDeng 于 2015-9-26 18:59 编辑 ]

授人以渔,不授人以鱼。
2015-09-26 18:55
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
仔細看17樓的源代碼:新vc版本和舊版本fopen()函數的區別就在這裡。新版本的函數,返回操作系統定義的錯誤碼,依據這個錯誤碼,可以查閱到fopen()函數到底是什麼原因失敗,是(讀時)文件不存在?抑或是沒有在目錄上讀寫文件的權限?失敗的原因很多,具體是哪種,都由這個錯誤碼反饋回來。然而,舊版本的fopen()是沒有這種功能的。

錯誤碼對應的文字信息,可以這裡查到:https://msdn.(v=vs.85).aspx
比如,錯誤碼2,表示“文件不存在”,而錯誤碼3,則表示“路徑不存在”……有些時候,文件名是沒有寫錯,但路徑名寫錯了,就會老問明明文件存在,怎麼不能打開,殊不知是自己把路徑寫錯了,這種現象,你與其到處問人,不如自己用這個錯誤碼找到真正原因,因為別人不可能看到你機器上的文件到底放在哪裡跟你寫的有什麼不同,這樣你是永遠找不到答案的了。愛用舊版本機制的、愛用標準函數的,全都沒有這種功能,那就自求多福了。

你可以看到,針對舊版本函數,我祗能返回非零——是的,就是!0,不是1,也不是別的什麼具體非零値,!0到底是什麼値,我也不知道。對C語言來說,邏輯假衹有一個値零,但邏輯真卻有無數個値,包括負數,不要以為1才是真,更不要用==1來判斷邏輯真。

[ 本帖最后由 TonyDeng 于 2015-9-26 19:20 编辑 ]

授人以渔,不授人以鱼。
2015-09-26 19:11
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
實際上,把Copy_File()函數的參數形式套到main()的函數上,就是cmd內部指令copy的用法。cmd內部指令copy file1 file2,是把file1複製為file2,它本質上就是類似Copy_File(file2,file1)的另一種寫法。C語言習慣目標在前、源在後,所以我把Copy_File()的參數寫成那樣,祗要按照普通的習慣,兩個參數的角色對調,就是copy的用法。這個程序,假設程序文件名是mycopy,那麼可以做出指令mycopy file1 file2。

所謂C語言寫成系統組件,無非就是這樣,沒什麼神秘的,在DOS時代自然得很的東西,不知到後來怎麼會弄得那麼神秘,好像非要什麼?unix系統不可似的。愛用命令行,完全在cmd上使用系統就是了,又不是不行,是自己不會用、不知道指令罷了,拿著本系統手冊,有什麼不會的。

授人以渔,不授人以鱼。
2015-09-26 22:56
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
逐個字符複製,是最基本的。當要講求效率的時候,可以用fread()/fwrite()整塊整塊地讀寫,但由於文件大小一般不可能恰好是讀寫塊的整數倍,故到最後一塊,仍然有採用這種最原始的逐字符拷貝法收尾。整塊讀寫可以提高效率,但並非一塊越大越好,要通過實際運行調整才能找到最恰當塊尺寸的,因為那與很多因素有關,比如C運行庫內部的緩衝區、操作系統自身的緩衝區、磁盤硬件的讀寫速度等,都互相影響,不能想當然亂設塊尺寸的,一般來說,編譯器供應商默認的配置,是適應絕大多數情況的,不鼓勵程序員隨便“優化”,往往是越自以為是的優化,越弄巧反拙——寫最直接的代碼就是了。

這種情況,我曾經測試過:複製一個相當大的文件,程序短短十多秒就執行完結束了,返回操作系統了,但硬盤仍然在讀寫,整整一分鐘都沒停下來,可見程序結束跟真正操作結束根本不是一回事,你自己在程序中計時,那是騙自己的,事實上效率根本沒你計算的那麼高。

不過說來說去,這些東西跟C語言一點關係都沒有,是編程之前應有的系統基礎知識。那些連操作系統都不會操作、基本原理都不懂的,起手就學C語言,還專門做涉及這些知識的課題,那肯定做不來,但最慘的是卻因此以為是C語言沒學好、需要學這些語言之外的東西。C語言沒有那麼博大精深!其實學C語言並不難,難的是這些語言之外的專業知識。可惜這裡很多人都是該學的編程知識不學,愛鑽研編程之外的專業,當那些是編程了,學完了if、do、while、for了,就迫不及待地去刷題,鉤鉤、分數得了不少,但到最後做綜合項目,就兩眼一瞪,全部不會。

[ 本帖最后由 TonyDeng 于 2015-9-26 23:31 编辑 ]

授人以渔,不授人以鱼。
2015-09-26 23:14
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
程序代码:
#include <stdio.h>
#include <stdlib.h>

#define __VC__

/*
功能:複製文件
參數:sourceFilename -- 源文件名,可帶絕對或相對路徑
      targetFilename -- 目標文件名,可帶絕對或相對路徑
返回:如果操作成功,返回零,否則返回系統錯誤碼(非零),查閱此錯誤碼信息包含致錯原因
*/
int Copy_File(const char* sourceFilename, const char* targetFilename)
{
    FILE* source;            // 源文件句柄
    FILE* target;            // 目標文件句柄
    errno_t errorCode = 0;    // 錯誤碼
    int ch;                    // 文件讀寫的單個字節

#ifdef __VC__
    errorCode = fopen_s(&source, sourceFilename, "rb");        // 以二進制讀模式打開源文件
    if (errorCode != 0)
    {
        return errorCode;
    }
#else
    source = fopen(sourceFilename, "rb");
    if (source == NULL)
    {
        return !0;
    }
#endif
#ifdef __VC__
    errorCode = fopen_s(&target, targetFilename, "wb");        // 以二進制寫模式創建目標文件
    if (errorCode != 0)
    {
        fclose(source);
        return errorCode;
    }
#else
    target = fopen(targetFilename, "wb");
    if (target == NULL)
    {
        fclose(source);
        return !0;
    }
#endif

    // 複製
    for (ch = fgetc(source); ch != EOF; ch = fgetc(source))
    {
        fputc(ch, target);
    }

    fclose(target);            // 關閉目標文件,系統刷寫數據流至磁盤文件
    fclose(source);            // 關閉源文件

    return errorCode;
}

/*
功能:使用命令行參數,將第一個文件複製為第二個文件
*/
int main(int argc, char* argv[])
{
    const char* sourceFilename;
    const char* targetFilename;

    if (argc >= 3)
    {
        sourceFilename = argv[1];
        targetFilename = argv[2];
        Copy_File(sourceFilename, targetFilename);
    }

    return EXIT_SUCCESS;
}

授人以渔,不授人以鱼。
2015-09-27 11:12
快速回复:关于最简单的C语言文件操作的问题!
数据加载中...
 
   



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

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