在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘。可是,这两天,他又抱怨他的下载程序不好用,让我们帮他写一个下载程序。

虽然我们学了C语言,虽说学了C语言,走遍天下都不怕,但是要想用C语言写一个全新的下载程序,对我们来说,就好比另外一个二万五千里长征。虽然技术上可行,但是在实际操作中却是行不通的。谁也不会傻到去用C语言写一个全新的下载程序。那么,到底怎么办呢?

如果我们看了《C程序设计伴侣》的7.A 站在巨人的肩膀上——如何使用已有的函数库这个节,要想解决这个问题,那简直就是“洒洒水啦”。在这个小节中,我们介绍了如何借助一些已有的函数库来帮助我们高质量高效率地完成一些常见任务。而其中介绍的CURL,正好是一个可以用于网络下载的开源函数库。

实际上,CURL有两种工作方式,其一,它是一个用URL语法在命令行方式下工作的文件传输工具。我们可以使用curl.exe直接在命令行下下载文件。其二,它也是一个开源的函数库,它提供了libcurl这个函数库,其中提供了多个可以用于处理网络事务(诸如下载,登陆,POST等)的API,利用这些API,我们就可以轻松地完成一个下载程序,这就好像坐上了飞机,片刻之间,就从江西瑞金到了陕北延安,一步完成二万五千里长征。

CURL的使用非常简单,跟其他类似的开源的函数库一样,其使用分为编译函数库和使用函数库两个步骤。

编译CURL函数库

在这里,我们以在Windows环境下,利用Visual C++ 2012编译为例。如果是其他环境,可以参考其文档,也很详尽。

  1. 从CURL的官方网站上下载CURL的源代码包,并解压得到所有源代码
  2. 接下来的工作就是源代码编译成相应的函数库文件(lib和dll)了。这里有两种方法:
  3. 我们可以采用《C程序设计伴侣》中介绍的方法,用Visual Studio打开根目录下的vc6curl文件,经过项目转换后,使用Visual C++ 2012的IDE编译其中的libcurl项目。
  4. 更简便的,我们还可以在“VS2012开发人员命令行提示”中,使用nmake来编译整个源代码。
  5. 首先是启动位于开始->所有程序->Microsoft Visual Studio 2012->Visual Studio Tools中的命令提示,然后用cd命令进入源代码所在根目录下的winbuild目录,比如:     C:\Program Files\Microsoft Visual Studio 11.0>f:

F:\>cd code\curl-7.28.1d\winbuild

F:\code\curl-7.28.1d\winbuild>

  1. 然后,就是使用nmake编译整个代码了:     nmake /f Makefile.vc mode=dll vc=10      其中,mode=dll表示编译成动态链接库,而vc=10选择的是Visual C++的版本,本来Visual C++ 2012是vc11,但是CURL不支持,只好用2010的10代替了,编译也没有什么问题。
  2. 起来倒杯水的时间,整个编译就完成了,编译结果保存在     F:\code\curl-7.28.1d\builds\libcurl-vc10-x86-release-dll-ipv6-sspi-spnego-winssl/      目录下,其中bin保存了可以用于命令行的curl.exe应用程序和它用到的libcurl.dll,include目录是开发需要用到的头文件,lib目录下是需要用到的库文件。
  3. 最后的工作,就是安装libcurl函数库。     将/builds/lib/目录下的文件复制到编译器的库文件目录,例如,E:\MinGW\lib\      将/builds/include/目录下的文件复制到编译器的头文件目录,例如,E:\MinGW\include\      将/builds/bin/目录下的libcurl.dll文件复制到操作系统的动态库搜索目录,例如,C:\Windows\System32\      或者可执行文件所在的目录      当然,我们可以通过配置开发工具来达到同样的目的,这里就不赘述了。
  4. 如果你嫌自己编译麻烦,CURL也提供已经编译好的二进制文件可以直接下载,不过我还是建议你自己动手编译,毕竟,这是我们每个程序员都需要掌握的基本功。

至此,整个编译安装过程就算完成了,这样我们就可以在我们自己的程序中调用CURL所提供的API来完成文件下载的功能。这就像飞机已经加满了油,正停在跑道上等待起飞!

塔台塔台,CL2013次航班准备完毕,请求起飞。

现在,我们就可以利用其中提供的API来简便地实现一个系在程序。

/**  get.c*  简易下载程序*  Created on: 2013年11月1日11:13:10*  Author: Bruce*/#include <curl/curl.h>
#include <string.h>
//用#pragam comment预编译命令,表示这个程序将使用libcurld_imp.lib这个文件
#pragma comment(lib,"libcurl.lib")//复制将数据写入文件的回调函数,关于回调函数,可以参考C程序设计伴侣8.5.4小节介绍
size_t write_data(void * ptr,size_t size,size_t nmemb,FILE * stream)
{int written  = fwrite(ptr,size,nmemb,stream);return written;
}//使用函数库所提供函数实现文件下载函数
CURLcode download(char * url,char * out)  //char * url待下载文件的URL,char * out 下载后的文件名
{CURL * curl = NULL;FILE * fp = NULL;CURLcode res;//调用函数库中的curl_easy_init()函数完成初始化curl = curl_easy_init();if(curl)  //判断初始化是否成功
    {//以二进制可写方式打开文件,保存下载得到的数据fp = fopen(out,"wb");//根据libcurl的使用方法,设定下载的URL,写入函数以及写入的文件
        curl_easy_setopt(curl,CURLOPT_URL,url);curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);//调用curl_easy_perform()函数执行下载操作res = curl_easy_perform(curl);//下载完成,进行最后的清理工作
        curl_easy_cleanup(curl);//关闭文件
        fclose(fp);return res;}else{//如果初始化失败,返回相应的错误代码return CURL_FAILED_INIT;}
}//辅助函数,用于从URL中获得文件名
void getfilename(char * url,char * name)
{//找到URL中的最后一个‘/’字符char* pos = strrchr(url,'/');if(NULL != pos){//将URL中文件名(从pos+1开始知道字符串结束)复制到name字符串中strcpy(name,pos+1);}
}//带有参数的主函数,可以让用户在执行时,直接输入待下载文件的URL
// 例如,如果我们想要下载libcurl的源代码包,则可以直接输入:
// get http://curl.haxx.se/download/curl-7.24.0.zip
// 关于带参数的主函数,可以参考8.7.3小节
int main(int argc,char* argv[])
{//获取用户输入的URL,判断使用方法是否正确if(2 != argc){// 提示正确的使用方法puts("usage: get http://curl.haxx.se/download/curl-7.24.0.zip");return -1;}//获取URL中的文件名char* url = argv[1];char name[32] = "";getfilename(url,name);// 调用函数库所提供函数实现的download()函数,  完成文件的下载CURLcode res = download(url,name);// 根据返回结果,提示用户下载成功与否if(CURLE_OK == res){printf("great! download %s as %s succesfully.",url,name);}else{printf("sorry:( cannot download %s.",url);}return 0;
}

代码中的注释已经非常详尽了,这里就不再多加解释了。如果看完注释,还是有不明白的地方,或者想更加深入地了解这个程序,

可以参考《C程序设计伴侣》的第七章关于这个例子的介绍。

现在,我们可以用如下命令编译这个程序:

cl /TP get.c
编译后,得到get.exe,也就是我们为下载狂人写的下载程序。(这里的/TP让你觉得有点不舒服? 那么看看学了C语言,如何利用cURL写一个下载程序?——在MinGW环境下实现) 下载程序的开发简单,其 使用就更简单了,比如我们要下载cURL的源代码, 可以使用下面的命令:

get.exe http://curl.haxx.se/download/curl-7.28.1.zip
利用cURL,不到一百行代码,我们轻松地完成了一个下载程序,当然,如果你有兴趣,还可以进一步完善,比如加上进度提示等等。 这个事例也告诉我们一个道理:

学会站在巨人的肩膀上,可以收到事半功倍的效果

我们介绍了如何在Windows平台的Visual C++环境下利用cURL快速高效地实现一个下载程序。但是有朋友反馈说,“这是在用C++代码冒充C代码”。这位朋友说的很有道理,这是因为 Visual C++对C语言的支持并不十分完善,为了使用C语言中的一些新特性,我在编译最终代码的时候,加上了一个/TP选项,这实际上是将.c文件当作.cpp文 件来编译了,也就是把C语言代码视作了C++代码。这里需要说明的是,我们在代码中用到的全是C语言,只是在编译的时候采取了一些曲线救国的策略。

虽然用/TP的方式可以解决问题,但是看起来总有些旁门左道的感觉。幸运的是,在Windows平台上,不只有Visual C++这一款编译器,还有其他的C语言编译器,比如,MInGW就是其中应用比较广泛的一款。利用MinGW,我们同样可以完成整个过程,同时还更加简 单。

  1. 编译libcurl函数库     在Visual C++环境下,我们是使用其nmake程序进行编译,而在MinGW环境下,我们使用其make程序编译(这里的前提是MinGW安装目录下的bin目录在系统PATH路径中)。首先进入cURL的源代码目录,然后用如下命令编译:      make mingw32      因为我们在这里只是使用cURL的基本功能,所以没有使用其他附加选项。
  2. 编译结果     很快我们就可以得到我们需要的编译结果(位于lib目录下):
  • libcurl.a 静态链接库文件
  • libcurldll.a 动态链接库的导入库
  • libcurl.dll 动态链接库

安装     MinGW环境下的安装同Visual C++环境下的安装相似:      头文件:将include目录下的curl目录复制到MinGW的头文件目录,比如:E:\MinGW\include      库文件:将上面编译得到的libcurl.a和libcurldll.a复制到MinGW的库文件目录,比如:E:\MinGW\lib      dll文件:将上面编译得到的libcurl.dll复制到系统PATH目录,比如,C:\Windows\System32使用     仍然使用我们在学了C语言,如何利用cURL写一个下载程序?——用cURL提供的API实现下载中介绍到的get.c文件,用下面的命令进行编译:      动态链接:gcc –o get.exe get.c –lcurldll      静态链接:gcc –o get.exe get.c –lcurl      这样,我们就得到了下载程序get.exe。

整体来看,MinGW环境下libcurl的使用跟在Visual C++环境下的使用是相似的,只是MinGW对C语言的支持根据完善,看起来更加名门正派一些。总之,两种环境下都可以实现,而具体使用哪一种,就看你自己的喜好了。

转自:http://www.howzhi.com/course/3387/lesson/43112

转载于:https://www.cnblogs.com/kingshow123/p/easydown.html

学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装相关推荐

  1. python抽奖游戏_利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    原标题:利用Python写一个抽奖程序,解密游戏内抽奖的秘密 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客 ...

  2. python抽奖教程_利用Python写一个抽奖程序,解密游戏内抽奖的秘密|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 分析需求 我们先整理下思路,目标是什么?目标是要写一个抽奖程序,那么抽奖程序的核心是什么?当然是如何判断一 ...

  3. python编程炒股案例_利用python写一个炒股程序

    本篇中,我们将通过技术分析流派中经典的"双均线策略",向大家展现如何在策略! 1. 准备工作? 一大波Python库需要在使用之前被导入: matplotlib用于绘制图表 num ...

  4. 【c语言写计算器】利用函数写一个计算器 包括菜单功能和加减乘除四个功能

    /*利用函数写一个计算器 包括菜单功能和加减乘除四个功能 作者:NBDR_YL*/ #include<stdio.h>int mean(void); //声明菜单的函数 float add ...

  5. 利用Flutter写一个跨平台的果核APP(4)——数据存储

    前言 目前我们已经实现了几个界面,今天这篇文章开始着手进行登录页的制作,主要流程就是获取输入框中的内容,发送给后台进行验证,如果成功将返回信息保存在本地并跳转至首页,如果失败就提示用户重新输入. 在这 ...

  6. 利用python写一个简单的双色球彩票系统

    利用python写一个简单的双色球彩票系统 1.设置每次买的号码一样 写一个双色球彩票系统,系统可以随机产生一组数据,一组彩票数据有六位数,这六位数的的取值范围是0和1. 一张彩票是两块钱,用户可以选 ...

  7. 利用Cocos2d-x写一个程序读取传奇wzl文件

    Cocos2d-x是一个用于游戏开发的开源框架,它提供了用于制作2D游戏的工具和功能.若要利用Cocos2d-x读取传奇wzl文件,需要对wzl文件的格式进行分析,并使用Cocos2d-x提供的读取文 ...

  8. 利用itchat写一个聊天机器人

    利用itchat写一个聊天机器人 聊天机器人 图灵机器人 需要的库 **自动回复私聊消息** **自动回复群聊消息** 结语: 聊天机器人 偶然在CSDN上看到大佬用20行教你写一个聊天机器人,觉得甚 ...

  9. 利用Flutter写一个跨平台的果核APP(0)——介绍

    前言 今年2月的时候,Google在开发者大会上推出了flutter的第一个预览版,我是在3月左右的时候才了解到这个全新的跨平台框架,并在阅读了相关文档之后写了一篇<你好,Flutter> ...

最新文章

  1. centos6.5安装hadoop2.6.4
  2. Groovy/Spock 测试导论
  3. Transaction 那点事儿,Spring事务管理
  4. Stanford CS230深度学习(五)CNN和ResNet
  5. oracle8i substr,Oracle中的INSTR,NVL和SUBSTR函数的用法详解
  6. Java 中override、overload、overwrite区别,以及与多态的关系
  7. ios刻录软件_好用免费的剪辑软件神器可以剪辑、导出,让大家都变成为大师级!...
  8. 计算H时M分S秒以后是_泵所需轴功率的计算方式
  9. 1块钱的路由器,10亿美金的小米网络
  10. 凤凰系统 android 分辨率,凤凰系统如何修改屏幕分辨率[多图]
  11. python判断信用卡号是否合法_怎么使用 Python 校验银行卡号码是否有效-阿里云开发者社区...
  12. 胡须清洗的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  13. 刚挣钱的程序员同学该如何花钱?
  14. 别只会搜日志了,求你懂点原理吧
  15. 【人工智能项目】缺陷检测分割数据集相关整理分享
  16. 有理数思维导图,七年级数学思维导图整理
  17. 御坂坂的C++学习之路(7)
  18. DVWA靶场通关教程
  19. 教育部“1+X”职业技能等级证书申报哪家好?学生应该如何选报?
  20. Mysql索引命中级别

热门文章

  1. 【教程】Linux 下软 RAID 实现方案!!
  2. java 单链表约瑟夫环_java循环单链表实现约瑟夫环问题
  3. Fluid 进入 CNCF Sandbox,加速大数据和 AI 应用拥抱云原生
  4. 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?
  5. Dubbo 迈出云原生重要一步 - 应用级服务发现解析
  6. 云原生生态周报 Vol.9| K8s v1.15 版本发布
  7. mysql pt_mysql之pt工具之pt-fifo-split用法介绍
  8. centos mate桌面_CentOS 7安装桌面汇总
  9. 动感英语笔记_【共同战“疫”】(一)滨海新区大港西苑小学英语教师团队
  10. sublime text3安装python插件和flake8_让你的代码符合PEP8标准——sublime text 2 安装及使用 Python Flake8 Lint 插件...