用C实现一个简单的对拍器

大一新生,首次创作,虚心受教。

实现思路:

一、需要一个输入文件(input.txt),两个对拍程序(main1.txt,main2.txt)

二、将标准输入重定向为input.txt。将标准输出分别重定向为output1.txt,output2.txt。

三、对两个输出文件进行比较,输出结果。

具体实现:

一、所需头文件

 1:  #include <stdio.h>
2: #include <stdlib.h>
3: #include <sys/file.h>
4: #include <unistd.h>
5: #include <sys/types.h>

二、文件重定向并进行系统调用执行main1.exe main2.txt

 1:      int fdout1 = open("stdout1.txt", O_RDWR|O_TRUNC|O_CREAT, 0);
2: int fdout2 = open("stdout2.txt", O_RDWR|O_TRUNC|O_CREAT, 0);

//以每次打开文件清零和如不存在便创建就打开两个输出文件

 3:      int fdin = open("stdin.txt", O_RDWR, 0);
4: int tempin = dup(STDIN_FILENO);

 5:     int tempout = dup(STDOUT_FILENO), line = 1;

//对标准输出输入描述符表进行拷贝,防止系统清除其指向的文件表

 6:      char buf1[4096], buf2[4096];
7:
8: dup2(fdin, STDIN_FILENO);

9: dup2(fdout1, STDOUT_FILENO);

//重定向

10:      if (system("main1.exe") == 127)
11: write(tempout, "NO EXE", 7);
12: fdin = open("stdin.txt", O_RDWR, 0);
13: dup2(fdin, STDIN_FILENO);

//可能有些同学要问了这里问什么要对标准输入重定向两次,具体解释略长参见后文。

14:      dup2(fdout2, STDOUT_FILENO);
15: if (system("main2.exe") == 127)
16: write(tempout, "NO EXE", 7);
17: dup2(tempout, STDOUT_FILENO);

//恢复标准输出

18:      lseek(fdout1, 0, SEEK_SET);
19: lseek(fdout2, 0, SEEK_SET);

//重置文件读取位置,具体解释同十三行后。

三、对输出文件的处理


 1 for(;;)
2 {
3 int n;
4
5 if ((n = read(fdout1, buf1, 4096)) > 0 && read(fdout2, buf2, 4096) > 0)
6 {
7 int i, j = 0;
8 char buffer[1024];
9
10 for (i = 0; i < n; i++)
11 {
12 buffer[j++] = buf1[i];
13 if (buf1[i] == buf2[i])
14 {
15 if (buf1[i] == ‘\n‘)
16 {
17 j = 0;
18 line++;
19 }
20 }
21 else
22 {
23 printf("The difference in line %d between stdout1.txt and stdout2.txt\n", line);
24 buffer[j] = ‘\0‘;
25 printf("%s\n", buffer);
26 buffer[--j] = buf2[i];
27 printf("%s\n", buffer);
28 break;
29
30 }
31 }
32 if (i != n)
33 break;
34
35 }
36 else
37 {
38 printf("Can‘t find difference in this instance\n");
39 break;
40 }
41 }

四、对上文问题的解释

以上的两个问题都是由于带缓冲区的文件读写和不带缓冲区的文件读写混用产生的问题。标准输出和标准输入是带缓冲区的,而read和write函数不带缓冲区,所以进行重定向时,一旦将不带缓冲区的用read打开的输入文件stdin.txt重定向到标准输入,则输入文件中的内容会被输入到缓冲区中,引起当前读写文件位置的变化,下次程序main2.exe引用的时候就会出现错误。同理在输出文件操作的时候也要进行当前读写位置的复原。

五、警告

本程序bug多多,但基本能用,尤其是本人原先不熟悉windows下的一下编程,完成后才发现用windows写一个bat程序要简单的多,这就造成了在windows环境下以linux系统命令编写的一个不伦不类的对拍程序。

由于程序写的确实有点烂,主要目的原来是想救一救我被学校评测网站虐的惨不忍睹的C语言习题,顺便熟悉一下进来学习的知识,所以想顺便放上来分享一下,欢迎各位园友指出错误,一定虚心受教。

目前的bug有:如果一行超出1024b,就会发生溢出;有些情况可能行号不太准确。

六、小感

第一次写文章,排版各方面不太熟悉,希望各位谅解。

源代码http://files.cnblogs.com/Bright-Star/main.zip

  

时间: 2024-10-11 21:16:55

用C实现一个简单的对拍器的相关文章

《Yii2 By Example》第2章:创建一个简单的新闻阅读器

第2章 创建一个简单的新闻阅读器 本章内容包含:创建第一个控制器,用于展示新闻条目列表和详情:学习控制器和视图之间的交互:自定义视图的布局. 本章结构如下: 创建控制器和动作 创建用于展示新闻列表的视图 控制器是如何将数据传送到视图的 例子--创建一个控制器,展示静态新闻条目列表和详情 将常用视图内容分割成多个可复用视图 例子--在视图中进行部分渲染 创建静态页面 在视图和布局之前共享数据 例子--根据URL参数更换布局背景 使用动态模块布局 例子--添加展示广告信息的动态盒 使用多个布局 例子

使用Python制作一个简单的刷博器

呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while count<10: count=count+1 #你要刷的博客 web.open_new_tab("http://www.cnblogs.com/smiler/archive/2010/04/20/1716418.html#2856973") time.sleep(1) else: os

Arachnid包含一个简单的HTML剖析器能够分析包含HTML内容的输入流

Arachnid是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并能够在Web站上的每个页面被解析之后增加几行代码调用. Arachnid的下载包中包含两个spider应用程序例子用于演示如何使用该框架. http://sourceforge.net/projects/arachnid/

C++ Primer 学习笔记_29_操作符重载与转换(4)--转换构造函数和类型转换运算符归纳、operator new 和 operator delete 实现一个简单内存泄漏跟踪器

C++ Primer 学习笔记_29_操作符重载与转换(4)--转换构造函数和类型转换运算符归纳.operator new 和 operator delete 实现一个简单内存泄漏跟踪器 一.转换构造函数 可以用单个实参来调用的构造函数定义从形参类型到该类型的一个隐式转换.如下: class Integral { public: Integral (int = 0); //转换构造函数 private: int real; }; Integral A = 1; //调用转换构造函数将1转换为In

使用lua实现一个简单的事件派发器

设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lua 5.2以上版本不需要): stdext.lua local _ipairs = ipairs function ipairs(t) local mt = getmetatable(t) if mt and mt.__ipairs then return mt.__ipairs(t) end re

自己动手实现一个简单的JSON解析器

1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 web 应用开发领域内,得益于 JavaScript 对 JSON 提供的良好支持,JSON 要比 XML 更受开发人员青睐.所以作为开发人员,如果有兴趣的话,还是应该深入了解一下 JSON 相关的知识.本着探究 JSON 原理的目的,我将会在这篇文章中详细向大家介绍一个简单的JSON解析器的解析流

实现了一个简单的cage变形器

今天实现了一个简单变形器,可以用一个网格的形状影响另一个网格的形状. 如图,蓝色网格的形状被灰色网格操控. 当前的算法非常简单,就是计算蓝色网格每个点到灰色网格每个点的距离,以距离x次方的倒数作为权重. 没有使用均值坐标等高级算法. cage deformer节点的参数如下: max neighbour是影响蓝色网格每个点的最大灰色网格顶点数 weight power是计算权重的参数 下一步可以利用这个变形器尝试复杂动画(例如骨骼绑定的角色)的有限元模拟.具体来说就是让骨骼参数驱动角色的精细网格

node.js 实现一个简单的登录拦截器

拦截器在web开发中随处可见,比如站点的管理后台,不说所有人都能进入,所以就需要做一个拦截器并友好的跳转到提示页. 下面我们简单实现一种,判断用户是否登录成功,登录不成功的用户自动重定向到登录页面. 首先我们实现一个过滤器 exports.checkAuth=function(req, res, next) {     var token = req.signedCookies.token;     if (token && req.session.user && req.

一个简单的拼写检查器

记得以前就看过这篇文章:How to write a spelling corrector,文章将贝叶斯原理运用于拼写检查,二十几行简单的Python的代码就实现了一个拼写检查器. 感叹数学的美妙之外,也很喜欢类似这样的文章,将一个问题的原理讲清楚,再配上一些代码实例做说明,从小见大,从浅入深,对人很有启发. 这里简单的介绍下基于贝叶斯原理的拼写检查原理,再给出一个java版和C#版的实现. 拼写检查器的原理:给定一个单词,选择和它最相似的拼写正确的单词,需要使用概率论,而不是基于规则的判断.给