用C实现一个简单的对拍器——致每个曾经为求AC披星戴月的程序员们
大一新生,首次创作,虚心受教。
实现思路:
一、需要一个输入文件(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披星戴月的程序员们的更多相关文章
- 使用lua实现一个简单的事件派发器
设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lu ...
- Arachnid包含一个简单的HTML剖析器能够分析包含HTML内容的输入流
Arachnid是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并 ...
- 自己动手实现一个简单的JSON解析器
1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 ...
- 使用Python制作一个简单的刷博器
呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while co ...
- 一个简单的json解析器
实现一个简单地json解析器. 两部分组成,词法分析.语法分析 词法分析 package com.mahuan.json; import java.util.LinkedList; import ja ...
- 用c#自己实现一个简单的JSON解析器
一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...
- 实现了一个简单的cage变形器
今天实现了一个简单变形器,可以用一个网格的形状影响另一个网格的形状. 如图,蓝色网格的形状被灰色网格操控. 当前的算法非常简单,就是计算蓝色网格每个点到灰色网格每个点的距离,以距离x次方的倒数作为权重 ...
- Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器
新建一个single view 工程: 关闭ARC , 在.xib视图文件上拖放一个UIImageView 两个UIButton ,一个UISlider ,布局如图. 并为他们连线, UIImage ...
- 利用poi包装一个简单的Excel读取器.一(适配一个Reader并提供readLine方法)
通常,读文本我们会使用BufferedReader,它装饰或者说管理了InputStreamReader,同时提供readLine()简化了我们对文本行的读取.就像从流水线上获取产品一样,每当取完一件 ...
随机推荐
- -_-#【Angular】自定义过滤器
AngularJS学习笔记 <!DOCTYPE html> <html ng-app="Demo"> <head> <meta chars ...
- 【数学】XMU 1597 GCD
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1597 题目大意: 求(am-bm, an-bn),结果取模1000000007,a,b ...
- STL_iterator迭代器(2)——几种迭代器对象的用法
要学会使用迭代器和容器以及算法,需要学习下面的新技术. 一.流和迭代器 本书的很多例子程序使用I/O流语句来读写数据.例如: int value; cout << "Enter ...
- Drainage Ditches - poj 1273(网络流模板)
题意:1是源点,m是汇点,求出来最大流量,没什么好说的就是练习最大流的模板题 ************************************************************* ...
- eclipse打开一闪而过,环境安装正确
一:查看错误信息 开始,运行->cmd.execd 进入eclipse目录D:\JavaTools\eclipse\eclipse.exe>eclipsec.exe,看console输出是 ...
- BitmapFactory.decodeByteArray() 返回null,分析与解决
问题描述:用android自带的Camera获取图片,上传至远程数据库中(mysql),以BLOB格式存储, 但在提取图片时,始终无法在android界面显示,示例代码如下: ..... .... ...
- iOS应用内语言切换功能
当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了.当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局.交互效果的转变,如微信,微博,QQ这类应用都有 ...
- Thinkpad Edge E440 Ubuntu14.04 无线网卡驱动 解决
http://ubuntuforums.org/showthread.php?t=2190347 正文: Thinkpad Edge E440 安装 Ubuntu12.04 后 无法使用无线网卡, 须 ...
- 使用一个小图片tile平铺到ImageView中或Activity背景
方法两种: 首先必须在res/drawable目录下包含一个background.jpg 方法1:在res/drawable中创建一个xml文件(background_repeat.xml) 内容为 ...
- Cookie Version in J2EE
Cookie Version in J2EE 原文章:http://villadora.me/2014/05/06/cookie-version/ 在处理Cookie的时候发现不能处理servlet ...