一个简单的c语言程序中缺个程序

C语言程序,一点都不懂!, C语言程序,一点都不懂! 以下
C语言程序,一点都不懂! 以下定义和语句struct
workers{}.year=1980; char name[20].s;pw=&w能给w中year成员赋1980的语句是A)*pw,*
B)w;} s.year=1980.year=1980;year=1980;C)pw-&
D)w;srruct{int day junjie90s C语言程序,一点都不懂!
Dw和pw都只能直接操作s;w,要想操作s中的year,两种方法pw-&gt.s = 1980.s.year = 1980;year
d
热心网友
D是对的!通过wp的正确方式应为:wp-&s.year=-2-413825人阅读
C语言(6)
前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法。学习任何一门语言,首先要掌握的肯定是语法。学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算机、手机等硬件设备)进行交互。由于我们的最终目的是学习iOS开发,学习iOS开发的话必须在Mac系统下,因此我就在Mac系统环境下开发C语言程序,而不是在Windows环境下。
接下来,就在Mac系统环境下编写第一个C语言程序,最后把程序运行起来,跟计算机做一个小小的互动
一、编写第一个C语言程序-Hello World
为什么称第一个程序为“Hello Wolrd”呢?其实计算机行业里面,学习任何技术的第一个程序都可以称为“Hello World”。“Hello World”的字面意思是“你好,世界”,也就是跟世界打招呼。我们第一个程序在这世界上诞生了,那肯定要跟世界打声招呼嘛,所以就称为“Hello World”。
1.用什么工具写代码
首先我们要做的肯定是写代码,在代码里面说清楚想要计算机做出怎样的操作。其实写代码就像平时写文章一样,只是在电脑上写一些文本内容,那用什么工具来写代码么?平时我们在Windows中写文章,可以用记事本、Word等文本编辑工具。在Mac中呢,我们可以安装一些文本编辑工具来写代码,比如。当然,在实际开发中,为了提高开发效率,一般会使用开发工具,,我在前面文章中已经说过了。不过呢,开发工具屏蔽了很多操作细节和语法细节,不利于初学者直观、系统地学习一门语言。因此,在这里,我们暂时使用文本编辑工具来写C语言代码。
1& C程序由函数构成
写代码之前,你首先要知道:任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,你可以说C语言程序是由函数构成的。
比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:
从上图可以看出:函数就是用来实现某个功能的程序段,每一个函数都有自己的功能。因此,你应该把实现某个功能所需的代码都写在函数中。比如,有个函数的功能是播放MP3,那么播放MP3的代码都应该写到这个函数中。当调用(执行)一个函数时,计算机就会按顺序执行函数中的所有代码,从而展示函数所实现的功能。一般来说,我们会将不同的功能交给不同的函数去实现。比如,将暂停播放MP3的代码写到一个函数中,将停止播放MP3的代码写到另一个函数中。因此,一个C程序中可能会有很多的函数。
2& C程序的入口
前面说到:一个C程序中可能会有很多的函数,这样就会有个疑问:当我们运行整个程序时,在众多函数中,计算机会先执行哪个函数呢?也就是说,一个C程序的入口在哪里?我写了几千行的代码,应该先从哪一行代码开始执行啊?是从第一行代码还是从最后一行代码开始执行啊?
其实,C程序的入口是一个名字叫做main的函数,简称main函数。(为了区分函数,每一个函数都有一个名称)也就是说,不管整个程序中有多少个函数,都是先执行main函数。不管main函数写在文件中间,还是文件末尾,也都是先执行main函数。
需要注意的是:
如果一个C程序中没有main函数,那么这个程序就不具备运行的能力。连程序的入口都没有,还运行什么?一个C程序中只能有一个main函数。想象一下也知道,如果有多个main函数,究竟先执行哪一个main函数呢?这会让计算机无法选择
3& 编写main函数
现在已经知道,要想运行一个C程序,必须有一个main函数,接下来就在文本编辑工具中编写一个main函数。main函数的格式大致如下:
第1行的int暂时不用去理解,先认为是main函数的固定写法第1行的main是函数名称,main后面的一对小括号()是函数的标志,绝对不能缺少!而且这对小括号是“英文括号()”,不是“中文括号()”!第2行开始,有一对大括号{},函数内部的代码都要写到这对大括号里面。每一个函数都有一对{},{}里面的内容可以称为“函数体”。在第3行添加了一行return 0;,暂时不用理解它的意思,先认为是main函数的固定写法。像第3行这种写在函数中的代码可以称为一条“语句”。写完一条语句后,要在尾部加上一个分号“;”,代表语句结束了
4& 编写输出语句
接下来在main函数中添加代码。
<span style="color:# #include &stdio.h&
<span style="color:#
<span style="color:# int main()
<span style="color:# {
<span style="color:#
printf(&Hello World\n&);
<span style="color:#
return <span style="color:#;
<span style="color:# }
在第5行添加了一条语句printf(&Hello World\n&);,这条语句的作用是让计算机在屏幕上输出用双引号&&括住的内容:Hello World,后面的&\n&是一个转义字符,表示回车换行,因此,输出Hello
Wrold这一串内容后会自动换行。至于为什么这条语句要这样写?为什么这条语句能让计算机输出东西?这些疑问都先搁着,以后会详细解释。为了保证第5行代码的正常使用,就在main函数的前面加了一行代码#include &stdio.h&,暂时不用去深刻了解它的意思,默默加上即可,注意,这里是不用加上分号&;&的当运行这个程序,就会先执行main函数,接着就会按顺序执行main函数大括号{}中的所有语句(第5行、第6行语句)需要注意的是:main函数中所有语句都必须写在第6行return 0;语句的前面,先别问为什么,以后会详细介绍
3.保存为C程序的源文件
代码写完了,总得保存起来吧,保存为什么&#26684;式的文件呢?每个文件都有自己的拓展名,不同的拓展名就代表着不同类型的文件,比如.mp3代表着音频文件,.txt代表着文本文件。我们前面编写的C语言代码,应该保存为一个拓展名为.c的文件,这个.c文件称为C语言程序的“源代码文件”,也称为“源文件”。
按下快捷键command &#43; s,输入文件名(我这里叫做one.c),选择文件&#26684;式
就这样,第一个C语言程序就写完了,非常简单吧,一点压力都没有
二、编译程序
前面已经把程序写好了,迫不及待想做的事情肯定是运行程序,看看计算机会有什么反应。遗憾的是,前面编写好的one.c文件还不能够运行。已经说过了,计算机只能识别0和1组成的机器指令,你现在写的这些什么int、main这些英文,它是看不懂的。我们需要使用C语言编译器,将源文件翻译成只有0和1的二进制文件,这个翻译过程,我们称之为“编译”。
Mac系统上支持一款叫做gcc的编译器,gcc支持多种编程语言:C语言、C&#43;&#43;、Objective-C、Java等。在后来,苹果公司自己开发了一款叫做clang的编译器,目标就是要超越gcc。我们这里就采用clang编译器来编译程序。要想在Mac中使用clang编译器,首先要安装一个命令行工具(Command Line Tools)
1.下载安装命令行工具
安装命令行工具的方式有2种。
1& 方式一:直接到
先点击屏幕左上角的“苹果图标”,查看你的Mac系统版本
如果你的Mac是Lion系统(版本&=10.7),请选择下载:如果你的Mac是Mountain Lion系统(版本&=10.8),请选择下载:
2& 方式二:先到安装Xcode,然后打开Xcode,在Xcode中安装命令行工具
2.打开终端
安装完命令行工具后,就可以使用clang编译器了。那怎么使用clang呢?通过在“终端”中输入相应的clang指令来启动编译器。
默认情况下,终端所指向的路径是用户的个人主文件夹,我的主文件夹是/Users/apple,我的用户名叫apple
3.跳转到one.c所在的路径
为了方便操作,我们应该将终端的路径切换到one.c所在的路径,one.c存放在我的桌面,文件夹路径是/Users/apple/Desktop
输入指令:cd /Users/apple/Desktop , 然后敲回车,指令&cd&是改变路径的意思。
4.输入编译指令,编译one.c文件
输入指令:cc -c one.c , 然后敲回车
指令&cc -c&表示编译某个源文件,后面跟上源文件的名称或者全路径。
如果敲完编译指令后,没有显示太多的信息,说明你编译成功了。编译成功后,会在终端所在的路径下生成一个二进制文件,称为“目标文件”,拓展名为&.o&,文件名与源文件一致。one.c文件编译成功后就生成了one.o文件。
补充:在开发过程中,不可能将所有的代码都写在一个.c文件中,为了模块化开发,一般会将不同的功能写到不同的源文件中。如果要同时编译多个源文件,这样写:cc -c one.c two.c three.c。源文件编译之后,每个源文件都会生成对应的.o文件,比如two.c生成了two.o、three.c生成了three.o
5.编译器的语法检测
编译器除了能将.c源文件编译成.o目标文件之外,还有一个非常重要的功能:语法检测。跟英语一样,C语言也有自己的语法,如果你不按照C语言语法去写代码,那就无法编译成功。生成目标文件之前,编译器会先检查.c文件是否有语法错误,如果出现语法错误,会列出错误的总个数、错误原因和错误代码的行号,这时候就不会产生目标文件;必须修正相应的语法错误,重新编译成功后,才会生成目标文件。
接下来我把代码故意写错,第3行把int写成了intt,第5行语句少了一个分号&;&
<span style="color:# #include &stdio.h&
<span style="color:#
<span style="color:# intt main()
<span style="color:# {
<span style="color:#
printf(&Hello World\n&)
<span style="color:#
return <span style="color:#;
<span style="color:# }
重新保存源文件,在终端中重新编译一下
它说得非常明显:有2个错误,第1个错误是在one.c的第3行,第2个错误是在one.c的第5行。这些错误信息(error)是一定要修改的,只要有一个错误信息存在,就不可能编译成功。以后还有可能会遇到一些“警告信息(warning)”,警告信息可以忽略,不影响编译。
三、链接程序
1.什么是链接
源文件编译成功后,会生成一个.o目标文件,这就是一个二进制文件,但是,还是不能运行。目标文件不能运行的主要原因有2个:
1& 在开发过程中,不可能将所有的代码都写在一个.c文件中,为了模块化开发,一般会将不同的功能写到不同的源文件中。源文件编译之后,每个源文件都有对应的.o文件,比如two.c生成了two.o、three.c生成了three.o,这些.o文件都不能单独运行,它们之间都有密不可分的关系,需要将所有相关联的.o目标文件组合在一起。
2& 除开组合所有的目标文件之后,还需要将C语言的函数库包含进来,才能生成可执行文件。
将所有相关联的.o目标文件、以及C语言函数库组合在一起生成可执行文件的过程,我们称为“链接”。
2.链接目标文件
在终端中输入指令:cc one.o , 然后敲回车。如果要同时链接多个目标文件,这样写:cc one.o two.o three.o
链接成功后,会生成一个可执行文件,默认的名称叫做“a.out”。由于我们是在mac系统下生成了可执行文件,mac系统是基于UNIX系统的,所以这个文件只能在UNIX系统中运行。如果是在Windows环境下,生成的可执行文件拓展名为&.exe&。
3.更改可执行文件的名称
如果想更改可执行文件的名称,可以输入指令:cc -o one one.o,-o后面跟上可执行文件的名称,因此可执行文件的名称就变成了one
4.连续执行编译、链接
其实也可以在终端中直接输入:cc one.c , 会按顺序执行编译、链接两个操作。
这条命令产生一个名为&a.out&的可执行程序。中间会产生一个名为one.o的目标文件,但它在链接完成后会被删除。
如果想修改可执行文件的名称,跟前面是一样的,指令为:cc -o abc one.c , 可执行文件的名称为abc
四、运行程序
经过前面几个步骤后,终于生成了可执行文件,接下来就可以运行这个程序了。运行程序有2种方式:
1.在终端中输入指令运行程序
在终端中输入:./a.out,敲回车就可以运行这个程序。这里a.out是可执行文件的名称。
敲完指令后,你会发现屏幕上输出了一句“Hello World”。就这样,我们成功跟计算机来了一点小小的互动,它替我们输出了一句文字。
2.双击可执行文件
直接双击a.out文件,选择用终端来运行程序
运行成功后
经过一番折腾,终于将第一个C程序运行成功了,总共有4个步骤:编写程序 -& 编译 -& 链接 -& 运行
需要注意的是:
中间某个环节出错了,那么就不会有后面的操作。比如编译出错了,那么就不可能有链接这个环节。如果你对源代码进行了修改,那么需要重新编译、链接之后再运行程序,这样才能看到最新的效果。
六、学习建议
1.学编程并不是学英文
写完这个Hello World程序后,可能很多人会去查单词,看看int什么意思、看看那stdio、return又是什么意思。其实,这是非常没必要的做法,我们学的是编程,并不是学英文,没有必要一个一个词语地去扣。再说,这些词语对计算机来说并不是什么英文单词,仅仅是个符号、是代码!!!计算机只能识别0和1,因此还要将这些代码编译成0和1之后才能被计算机所执行。计算机并不是有道词典,它不可能认识什么英文单词。很多代码都是固定写法,并没有太多的所谓英文含义。
2.程序的可读性
这个Hello World程序的功能很少,只有一丁点内容,我们就占用了好几行行代码。有人可能会问:这些代码一定要换行么?第5行prinf语句的前面一定要要缩进几个空&#26684;么?
其实,你完全可以不缩进
<span style="color:# #include &stdio.h&
<span style="color:#
<span style="color:# int main()
<span style="color:# {
<span style="color:# printf(&Hello World\n&);
<span style="color:# return <span style="color:#;
<span style="color:# }
也可以将所有的代码都写成一行(第1行代码比较特殊,必须独立一行)
<span style="color:# #include &stdio.h&
<span style="color:# int main()
{printf(&Hello World\n&);return <span style="color:#;}
这样写虽然没有问题,但是代码可读性非常地差,想象一下也知道:整个文件中就一行代码,如果这个程序很大的话,肯定很多代码,这样的代码是有多恶心啊!别人 可能根本看不太懂你写的是什么东西,甚至你自己都看不太懂。在工作中,我们难免会遇到难题,经常要求助于他人,但是别人要在看得懂我们代码的基础上,才能 帮我们解决问题啊。因此,代码的可读性很重要!一定要养成良好的编程习惯。
3.初学者不要过于寻根问底
当你对一门新技术还不是很了解的时候,你首先要做的事情是学会怎么使用它,先把它成功用起来,并不是从头到尾看清楚所有的源代码、把每一行代码中的每个词语都摸清楚什么意思,完全没有这个必要。等你有一定的技术基础了,这门技术用得很熟了,而且时间和能力允许的话,才有必要去寻根问底地解读所有的源代码。所以,第一个C程序的代码中很多不懂的地方,暂时不用去纠结,学到后面了,你就会不自觉地就知道它们是什么意思了。
七、clang指令汇总
这些指令不用去死记,大致有个了解,用到时再来查资料即可
1.编译单个c源文件,并产生一个目标文件
cc -c one.c
这条命令产生一个名为one.o的目标文件
2.编译多个c源文件,并为每个文件产生一个目标文件
cc -c one.c two.c three.c
这条命令产生3个目标文件:one.o、two.o、three.o
3.链接单个目标文件
这条命令产生一个名为a.out的可执行文件
4.链接多个目标文件
cc&one.o two.o three.o
这条命令产生一个名为a.out的可执行文件
5.编译并链接一个c源文件
这条命令产生一个名为a.out的可执行文件。中间会产生一个名为one.o的目标文件,但它在链接过程完成后会被删除。
6.编译并链接多个c源文件
cc&one.c two.c three.c
这条命令产生一个名为a.out的可执行文件。当编译的源文件超过一个时,目标文件便不会被删除。这就允许你对程序进行修改后,只对那些进行过改动的源文件进行重新编译。
7.编译一个c源文件,并把它和现存的目标文件链接在一起
cc&one.o two.o three.c
这条命令产生一个名为a.out的可执行文件
8.上面那些可以产生可执行文件的指令均可以加上“-o name”这个选项,产生的可执行文件就叫做name
比如 cc&-o abc one.c
这条指令会产生一个名为abc的可执行文件
9.执行可执行文件
这条指令可以执行一个名为a.out的可执行文件
感谢来自/mjios/archive//3062576.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:34549次
排名:千里之外
转载:43篇
(2)(1)(2)(6)(3)(3)(1)(1)(1)(35)有个C语言程序看不懂了,求大神详解, 有个C语言程序看不懂了,求大神
有个C语言程序看不懂了,求大神详解 #include&stdio.h&main(){ char ch[7]=&65ab21&;int i,s=0;
for(i=0;缉沪光疚叱狡癸挟含锚ch[i]&=&#39;0&#39; && ch[i]&=&#39;9&#39;;i+=2)
s=10*s+ch[i]-&#39;0&#39;;
printf(&%d&#92;n&,s);}这个程序为何输出为6? 匿名 有个C语言程序看不懂了,求大神详解
chi[0] 是 &#39;6&#39; 满足 ch[0]&=&#39;0&#39; && ch[0]&=&#39;9&#39;执行s=10*s+ch[i]-&#39;0&#39;;
即s=10*0+‘6’-‘0’=6s从零变为6i+=2i从零变为2i=2ch[2]是&#39;a&#39; 不符合ch[2]&=&#39;0&#39; && ch[2]&=&#39;9&#39;  这时for循环就结束了 所以printf 输出是6
for(表达式1;表达式2;表达式3)在表达式2值为真(1)的时候继续运行。首先读入ch[0],ch[0]==&#39;6&#39;,ch[i]-&#39;0&#39;是吧字符的数字转换为int数字,所以s=s*10+6,此时s=6然而,i++之后i==2,此时a[2]==&#39缉沪光疚叱狡癸挟含锚;a&#39;,表达式2不成立退出循环,于是酒输出6
只执行了一次for循环,因为当i+=2的时候ch[i]是为字符&#39;a&#39;的,所以条件不成立。直接是10*0+&#39;6&#39;-&#39;0&#39; == 6。
char 对应的是ascii码,你带进去跟着算一下就好了
应该是不符合条件退出了,至于什么原因,暂不清楚博客访问: 793623
博文数量: 394
博客积分: 2147
博客等级: 大尉
技术积分: 3493
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
以下是参考中讲解web应用http协议的时候,实现的一个简单的http程序,包含一个服务器和一个客户端。
先贴上客户端的程序:
/*************************************************************************
&* Copyright (c)
by xuwm All Rights Reserved
&* FILENAME:& WebClnt.c
&* PURPOSE :& HTTP 客户端程序, 获取网页.
&* AUTHOR& :& 许文敏
&**************************************************************************/
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")& /* WinSock使用的库函数 */
/* 定义常量 */
#define HTTP_DEF_PORT&&&& 80& /* 连接的缺省端口 */
#define HTTP_BUF_SIZE&& 1024& /* 缓冲区的大小&& */
#define HTTP_HOST_LEN&&& 256& /* 主机名长度 */
char *http_req_hdr_tmpl = "GET %s HTTP/1.1\r\n"
&&&&"Accept: image/gif, image/jpeg, */*\r\nAccept-Language: zh-cn\r\n"
&&&&"Accept-Encoding: gzip, deflate\r\nHost: %s:%d\r\n"
&&&&"User-Agent: Huiyong's Browser \r\nConnection: Keep-Alive\r\n\r\n";
/**************************************************************************
&* 函数功能: 解析命令行参数, 分别得到主机名, 端口号和文件名. 命令行格式:
&*&&&&&&&&&& [:8080/index.html]
&* 参数说明: [IN]& buf, 字符串指针数组;
&*&&&&&&&&&& [OUT] host, 保存主机;
&*&&&&&&&&&& [OUT] port, 端口;
&*&&&&&&&&&& [OUT] file_name, 文件名;
&* 返 回 值: void.
&**************************************************************************/
void http_parse_request_url(const char *buf, char *host,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned short *port, char *file_name)
&&&&int length = 0;
&&&&char port_buf[8];
&&&&char *buf_end = (char *)(buf + strlen(buf));
&&&&char *begin, *host_end, *colon, *
&&&&/* 查找主机的开始位置 */
&&&&begin = const_cast(strstr(buf, "//"));
&&&&begin = (begin ? begin + 2 : const_cast(buf));
&&&&colon = strchr(begin, ':');
&&&&host_end = strchr(begin, '/');
&&&&if (host_end == NULL)
&&&&&&&&host_end = buf_
&&&&{&& /* 得到文件名 */
&&&&&&&&file = strrchr(host_end, '/');
&&&&&&&&if (file && (file + 1) != buf_end)
&&&&&&&&&&&&strcpy(file_name, file + 1);
&&&&if (colon) /* 得到端口号 */
&&&&&&&&colon++;
&&&&&&&&length = host_end -
&&&&&&&&memcpy(port_buf, colon, length);
&&&&&&&&port_buf[length] = 0;
&&&&&&&&*port = atoi(port_buf);
&&&&&&&&host_end = colon - 1;
&&&&/* 得到主机信息 */
&&&&length = host_end -
&&&&memcpy(host, begin, length);
&&&&host[length] = 0;
int main(int argc, char **argv)
&&&&WSADATA wsa_
&&&&SOCKET& http_sock = 0;&&&&&&&& /* socket 句柄 */
&&&&struct sockaddr_in serv_& /* 服务器地址 */
&&&&struct hostent *host_
&&&&int result = 0, send_
&&&&char data_buf[HTTP_BUF_SIZE];
&&&&char host[HTTP_HOST_LEN] = "127.0.0.1";
&&&&unsigned short port = HTTP_DEF_PORT;
&&&&char file_name[HTTP_HOST_LEN] = "index.html";
&&&&char file_nameforsave[HTTP_HOST_LEN] = "index1.html";
&&&&FILE *file_
&&&&if (argc != 2)
&&&&&&&&printf("[Web] input : %s [:8080]/index.html", argv[0]);
&&&&&&&&return -1;
&&&&http_parse_request_url(argv[1], host, &port, file_name);
&&&&WSAStartup(MAKEWORD(2,0), &wsa_data); /* 初始化 WinSock 资源 */
&&&&addr = inet_addr(host);
&&&&if (addr == INADDR_NONE)
&&&&&&&&host_ent = gethostbyname(host);
&&&&&&&&if (!host_ent)
&&&&&&&&&&&&printf("[Web] invalid host\n");
&&&&&&&&&&&&return -1;
&&&&&&&&memcpy(&addr, host_ent->h_addr_list[0], host_ent->h_length);
&&&&/* 服务器地址 */
&&&&serv_addr.sin_family = AF_INET;
&&&&serv_addr.sin_port = htons(port);
&&&&serv_addr.sin_addr.s_addr =
&&&&http_sock = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */
&&&&result = connect(http_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
&&&&if (result == SOCKET_ERROR) /* 连接失败 */
&&&&&&&&closesocket(http_sock);
&&&&&&&&printf("[Web] fail to connect, error = %d\n", WSAGetLastError());
&&&&&&&&return -1;
&&&&/* 发送 HTTP 请求 */
&&&&send_len = sprintf(data_buf, http_req_hdr_tmpl, argv[1], host, port);
&&&&result = send(http_sock, data_buf, send_len, 0);
&&&&if (result == SOCKET_ERROR) /* 发送失败 */
&&&&&&&&printf("[Web] fail to send, error = %d\n", WSAGetLastError());
&&&&&&&&return -1;
&&&&file_web = fopen(file_nameforsave, "a+");
&&&&do /* 接收响应并保存到文件中 */
&&&&&&&&result = recv(http_sock, data_buf, HTTP_BUF_SIZE, 0);
&&&&&&&&if (result > 0)
&&&&&&&&&&&&fwrite(data_buf, 1, result, file_web);
&&&&&&&&&&&&/* 在屏幕上输出 */
&&&&&&&&&&&&data_buf[result] = 0;
&&&&&&&&&&&&printf("%s", data_buf);
&&&&} while(result > 0);
&&&&fclose(file_web);
&&&&closesocket(http_sock);
&&&&WSACleanup();
&&&&return 0;
&首先在vs2010中的,添加一个VC命令行程序,把上面的程序直接放到主程序对应的cpp文件中,然后编译即可。
再贴上服务端的程序:
/*************************************************************************
&* Copyright (c)
by xuwm All Rights Reserved
&* FILENAME:& WebSrv.c
&* PURPOSE :& HTTP 服务器程序, 向客户端提供请求的文件内容.
&* AUTHOR& :& 许文敏
&**************************************************************************/
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")& /* WinSock使用的库函数 */
/* 定义常量 */
#define HTTP_DEF_PORT&&&&&&& 80&&&& /* 连接的缺省端口 */
#define HTTP_BUF_SIZE&&&&& 1024&&&& /* 缓冲区的大小 */
#define HTTP_FILENAME_LEN&& 256&&&& /* 文件名长度 */
/* 定义文件类型对应的 Content-Type */
struct doc_type
&&&&char * /* 文件后缀 */
&&&&char *&& /* Content-Type */
struct doc_type file_type[] =
&&&&{"html",&&& "text/html"& },
&&&&{"gif",&&&& "image/gif"& },
&&&&{"jpeg",&&& "image/jpeg" },
&&&&{ NULL,&&&&& NULL&&&&&&& }
char *http_res_hdr_tmpl = "HTTP/1.1 200 OK\r\nServer: Huiyong's Server \r\n"
&&&&"Accept-Ranges: bytes\r\nContent-Length: %d\r\nConnection: close\r\n"
&&&&"Content-Type: %s\r\n\r\n";
/**************************************************************************
&* 函数功能: 根据文件后缀查找对应的 Content-Type.
&* 参数说明: [IN] suffix, 文件名后缀;
&* 返 回 值: 成功返回文件对应的 Content-Type, 失败返回 NULL.
&**************************************************************************/
char *http_get_type_by_suffix(const char *suffix)
&&&&struct doc_type *
&&&&for (type = file_ type-> type++)
&&&&&&&&if (strcmp(type->suffix, suffix) == 0)
&&&&&&&&&&&&return type->
&&&&return NULL;
/**************************************************************************
&* 函数功能: 解析请求行, 得到文件名及其后缀. 请求行格式:
&*&&&&&&&&&& [GET
&* 参数说明: [IN]& buf, 字符串指针数组;
&*&&&&&&&&&& [IN]& buflen, buf 的长度;
&*&&&&&&&&&& [OUT] file_name, 文件名;
&*&&&&&&&&&& [OUT] suffix, 文件名后缀;
&* 返 回 值: void.
&**************************************************************************/
void http_parse_request_cmd(char *buf, int buflen, char *file_name, char *suffix)
&&&&int length = 0;
&&&&char *begin, *end, *
&&&&/* 查找 URL 的开始位置 */
&&&&begin = strchr(buf, ' ');
&&&&begin += 1;
&&&&/* 查找 URL 的结束位置 */
&&&&end = strchr(begin, ' ');
&&&&*end = 0;
&&&&bias = strrchr(begin, '/');
&&&&length = end -
&&&&/* 找到文件名的开始位置 */
&&&&if ((*bias == '/') || (*bias == '\\'))
&&&&&&&&bias++;
&&&&&&&&length--;
&&&&/* 得到文件名 */
&&&&if (length > 0)
&&&&&&&&memcpy(file_name, bias, length);
&&&&&&&&file_name[length] = 0;
&&&&&&&&begin = strchr(file_name, '.');
&&&&&&&&if (begin)
&&&&&&&&&&&&strcpy(suffix, begin + 1);
/**************************************************************************
&* 函数功能: 向客户端发送 HTTP 响应.
&* 参数说明: [IN]& buf, 字符串指针数组;
&*&&&&&&&&&& [IN]& buf_len, buf 的长度;
&* 返 回 值: 成功返回非0, 失败返回0.
&**************************************************************************/
int http_send_response(SOCKET soc, char *buf, int buf_len)
&&&&int read_len, file_len, hdr_len, send_
&&&&char *
&&&&char read_buf[HTTP_BUF_SIZE];
&&&&char http_header[HTTP_BUF_SIZE];
&&&&char file_name[HTTP_FILENAME_LEN] = "index.html", suffix[16] = "html";
&&&&FILE *res_
&&&&/* 得到文件名和后缀 */
&&&&http_parse_request_cmd(buf, buf_len, file_name, suffix);
&&&&res_file = fopen(file_name, "rb+"); /* 用二进制格式打开文件 */
&&&&if (res_file == NULL)
&&&&&&&&printf("[Web] The file [%s] is not existed\n", file_name);
&&&&&&&&return 0;
&&&&fseek(res_file, 0, SEEK_END);
&&&&file_len = ftell(res_file);
&&&&fseek(res_file, 0, SEEK_SET);
&&&&type = http_get_type_by_suffix(suffix); /* 文件对应的 Content-Type */
&&&&if (type == NULL)
&&&&&&&&printf("[Web] There is not the related content type\n");
&&&&&&&&return 0;
&&&&/* 构造 HTTP 首部,并发送 */
&&&&hdr_len = sprintf(http_header, http_res_hdr_tmpl, file_len, type);
&&&&send_len = send(soc, http_header, hdr_len, 0);
&&&&//send_len=1;
&&&&if (send_len == SOCKET_ERROR)
&&&&&&&&fclose(res_file);
&&&&&&&&printf("[Web] Fail to send, error = %d\n", WSAGetLastError());
&&&&&&&&return 0;
&&&&do /* 发送文件, HTTP 的消息体 */
&&&&&&&&read_len = fread(read_buf, sizeof(char), HTTP_BUF_SIZE, res_file);
&&&&&&&&if (read_len > 0)
&&&&&&&&&&&&send_len = send(soc, read_buf, read_len, 0);
&&&&&&&&&&&&file_len -= read_
&&&&} while ((read_len > 0) && (file_len > 0));
&&&&fclose(res_file);
&&&&return 1;
int main(int argc, char **argv)
&&&&WSADATA wsa_
&&&&SOCKET& srv_soc = 0, acpt_& /* socket 句柄 */
&&&&struct sockaddr_in serv_&& /* 服务器地址& */
&&&&struct sockaddr_in from_&& /* 客户端地址& */
&&&&char recv_buf[HTTP_BUF_SIZE];
&&&&unsigned short port = HTTP_DEF_PORT;
&&&&int from_len = sizeof(from_addr);
&&&&int result = 0, recv_
&&&&if (argc == 2) /* 端口号 */
&&&&&&&&port = atoi(argv[1]);
&&&&WSAStartup(MAKEWORD(2,0), &wsa_data); /* 初始化 WinSock 资源 */
&&&&srv_soc = socket(AF_INET, SOCK_STREAM, 0); /* 创建 socket */
&&&&if (srv_soc == INVALID_SOCKET)
&&&&&&&&printf("[Web] socket() Fails, error = %d\n", WSAGetLastError());
&&&&&&&&return -1;
&&&&/* 服务器地址 */
&&&&serv_addr.sin_family = AF_INET;
&&&&serv_addr.sin_port = htons(port);
&&&&serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
&&&&result = bind(srv_soc, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
&&&&if (result == SOCKET_ERROR) /* 绑定失败 */
&&&&&&&&closesocket(srv_soc);
&&&&&&&&printf("[Web] Fail to bind, error = %d\n", WSAGetLastError());
&&&&&&&&return -1;
&&&&result = listen(srv_soc, SOMAXCONN);
&&&&printf("[Web] The server is running ... ...\n");
&&&&while (1)
&&&&&&&&acpt_soc = accept(srv_soc, (struct sockaddr *) &from_addr, &from_len);
&&&&&&&&if (acpt_soc == INVALID_SOCKET) /* 接受失败 */
&&&&&&&&&&&&printf("[Web] Fail to accept, error = %d\n", WSAGetLastError());
&&&&&&&&&&&&
&&&&&&&&printf("[Web] Accepted address:[%s], port:[%d]\n",
&&&&&&&&&&&&inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));
&&&&&&&&recv_len = recv(acpt_soc, recv_buf, HTTP_BUF_SIZE, 0);
&&&&&&&&if (recv_len == SOCKET_ERROR) /* 接收失败 */
&&&&&&&&&&&&closesocket(acpt_soc);
&&&&&&&&&&&&printf("[Web] Fail to recv, error = %d\n", WSAGetLastError());
&&&&&&&&&&&&
&&&&&&&&recv_buf[recv_len] = 0;
&&&&&&&&/* 向客户端发送响应数据 */
&&&&&&&&result = http_send_response(acpt_soc, recv_buf, recv_len);
&&&&&&&&closesocket(acpt_soc);
&&&&closesocket(srv_soc);
&&&&WSACleanup();
&&&&printf("[Web] The server is stopped.\n");
&&&&return 0;
&这个也跟客户端程序一样,打开VS2010,新建一个VC命令行程序,COPY上面的代码,直接放到主程序的CPP文件中,编译即可。
运行代码如下:
1.先运行服务端程序,绑定端口,然后开启监听& 在CMD里先切换到exe的目录,然后 输入 服务端程序名.exe 9000,此处服务端程序名换成对应的程序名称.后面的9000端口号,也可以换成别的。
&2. 再运行客户羰程序,同上面一样,切换到exe&的目录,然后输入 客户端程序名.exe ,& 此处客户端程序名换成对应的程序名称,后面的,代表请求的网页路径。
&3. 在服务器的exe目录下,应创建一个index.html文件,里面可以输入一个正规的html文件。
以上只是学习网络编程的一点小体会,尽当以后温故:)
阅读(2771) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 16个流水灯c语言程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信