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

实现思路:

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

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

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

具体实现:

一、所需头文件

 :  #include <stdio.h>
: #include <stdlib.h>
: #include <sys/file.h>
: #include <unistd.h>
: #include <sys/types.h>

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

 :      int fdout1 = open("stdout1.txt", O_RDWR|O_TRUNC|O_CREAT, );
: int fdout2 = open("stdout2.txt", O_RDWR|O_TRUNC|O_CREAT, );
//以每次打开文件清零和如不存在便创建就打开两个输出文件
 :      int fdin = open("stdin.txt", O_RDWR, );
: int tempin = dup(STDIN_FILENO);
:     int tempout = dup(STDOUT_FILENO), line = ;
//对标准输出输入描述符表进行拷贝,防止系统清除其指向的文件表

 :      char buf1[], buf2[];
:
: dup2(fdin, STDIN_FILENO);
: dup2(fdout1, STDOUT_FILENO);
//重定向

:      if (system("main1.exe") == )
: write(tempout, "NO EXE", );
: fdin = open("stdin.txt", O_RDWR, );
: dup2(fdin, STDIN_FILENO);
//可能有些同学要问了这里问什么要对标准输入重定向两次,具体解释略长参见后文。

:      dup2(fdout2, STDOUT_FILENO);
: if (system("main2.exe") == )
: write(tempout, "NO EXE", );
: dup2(tempout, STDOUT_FILENO);

//恢复标准输出

:      lseek(fdout1, , SEEK_SET);
: lseek(fdout2, , SEEK_SET);

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

三、对输出文件的处理

 for(;;)
{
int n; if ((n = read(fdout1, buf1, )) > && read(fdout2, buf2, ) > )
{
int i, j = ;
char buffer[]; for (i = ; i < n; i++)
{
buffer[j++] = buf1[i];
if (buf1[i] == buf2[i])
{
if (buf1[i] == '\n')
{
j = ;
line++;
}
}
else
{
printf("The difference in line %d between stdout1.txt and stdout2.txt\n", line);
buffer[j] = '\0';
printf("%s\n", buffer);
buffer[--j] = buf2[i];
printf("%s\n", buffer);
break; }
}
if (i != n)
break; }
else
{
printf("Can't find difference in this instance\n");
break;
}
}

四、对上文问题的解释

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

五、警告

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

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

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

六、小感

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

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

  

用C实现一个简单的对拍器——致每个曾经为求AC披星戴月的程序员们的更多相关文章

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

    设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lu ...

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

    Arachnid是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并 ...

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

    1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 ...

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

    呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while co ...

  5. 一个简单的json解析器

    实现一个简单地json解析器. 两部分组成,词法分析.语法分析 词法分析 package com.mahuan.json; import java.util.LinkedList; import ja ...

  6. 用c#自己实现一个简单的JSON解析器

    一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...

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

    今天实现了一个简单变形器,可以用一个网格的形状影响另一个网格的形状. 如图,蓝色网格的形状被灰色网格操控. 当前的算法非常简单,就是计算蓝色网格每个点到灰色网格每个点的距离,以距离x次方的倒数作为权重 ...

  8. Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器

    新建一个single view 工程: 关闭ARC , 在.xib视图文件上拖放一个UIImageView  两个UIButton ,一个UISlider ,布局如图. 并为他们连线, UIImage ...

  9. 利用poi包装一个简单的Excel读取器.一(适配一个Reader并提供readLine方法)

    通常,读文本我们会使用BufferedReader,它装饰或者说管理了InputStreamReader,同时提供readLine()简化了我们对文本行的读取.就像从流水线上获取产品一样,每当取完一件 ...

随机推荐

  1. 本地存储-webStorage

    webStorage 提供了一种方式让网站能够把信息存储到你本地的计算机上,并在以后需要的时候进行获取.这个概念和cookie相似,区别是它是为了更大容量存储设计的.Cookie的大小是受限的,并且每 ...

  2. Emacs添加主题插件(Win系统)

    Emacs添加主题插件(Win系统) */--> /* @licstart The following is the entire license notice for the JavaScri ...

  3. win7怎么安装消息队列 MSMQ

    win7般都默认装了消息队列只需要进入 控制面板-程序-程序和功能-已安装更新-打开或关闭windows功能 勾选 Microsoft Message Queue (MSMQ)服务器 启动服务 行了: ...

  4. UVAlive3211 Now or later(2-SAT)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33799 [思路] 2-SAT. 二分安全间隔x,先到为1后到为0, ...

  5. 果酷:80后IT男“鲜果切”年入千万 _ 财经频道 _ 东方财富网(Eastmoney.com)

    果酷:80后IT男"鲜果切"年入千万 _ 财经频道 _ 东方财富网(Eastmoney.com) 果酷:80后IT男"鲜果切"年入千万

  6. selenium webdriver python 开始

    学习资料: Selenium with Python: http://selenium-python.readthedocs.org/en/latest/index.html 乙醇的python se ...

  7. 从APP消息推送所理解的观察者模式

    #1.什么是观察者模式? 观察者模式=(出版者+订阅者)模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能 ...

  8. 生成唯一的id(转)

    很多朋友都利用md5()来生成唯一的编号,但是md5()有几个缺点:1.无序,导致数据库中排序性能下降.2.太长,需要更多的存储空间.其实PHP中自带一个函数来生成唯一的id,这个函数就是uniqid ...

  9. 零基础学习云计算及大数据DBA集群架构师【Linux Bash Shell编程及系统自动化2015年1月21日周四】

    lvy老师教项目课程,以及代课了shell部分课程,大家都觉得这位老师不行,上课时做的操作很多都是错误的,觉得她基础不好.而且,她不能解释原因,学生问为什么,她不知道.崩溃啊.向xx培训机构反应后,说 ...

  10. Linux 机器之间建立互信

    原理: 就是两台机器(web-1和web-2)经过预先设置好经过认证的key文件,双方互相访问时,进行自动认证,从而实现互信.   互信的原理了解了,我们可以把配置ssh互信的步骤进行有效的分割. 1 ...