用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()简化了我们对文本行的读取.就像从流水线上获取产品一样,每当取完一件 ...
随机推荐
- C#编译时出现“不安全代码只会在使用 /unsafe 编译的情况下出现”错误的解决
原因是:在编译的代码里面有不安全类型unsafe方法或类!解决方法:将项目属性页中生成下的“允许不安全代码”复选框打上对勾即可,方法如下:项目属性对话框->生成->允许不安全代码块 选中即 ...
- 详解C语言的main函数
如图所示:#include<stdio.h>这是一个头文件,包含的是C程序运行的C语言的库函数,只有包含了相关的头文件,在程序中才能调用.stdio表示输入输出控制.printf():就是 ...
- require js 将config和入口函数分开写
原文地址 https://github.com/jrburke/requirejs/issues/354 Area there any plans to standardize/recommend a ...
- [Java] JVM 在执行 main 方法前的行为
JVM 执行一个 Java 程序时,先从某个指定的 Java 类的 main 方法开始执行代码,同时,传一个字符串数组作为 main 方法的参数.例如在 Unix 系统上,执行下面的命令 java T ...
- openstack theme topic
- WebLogic简单的备份和恢复
万一发生故障,为了迁移或者恢复WebLogic域,应定期地备份管理服务器机器上的整个域目录树.这样,只需恢复域目录并重启管理服务器就可以使服务器从硬件或者系统故障中恢复.在WebLogic生产域中,需 ...
- Asp.Net读取服务器EXE文件的方法!(超简单实例)
Asp.Net读取服务器EXE文件的方法!(超简单实例) Process process = new Process(); process.StartInfo.FileName = "d:\ ...
- sql 处理以字符隔开的字符串(类似split)
sql 处理以字符隔开的字符串(类似split)的处理方法. CREATE PROCEDURE dbo.Vip_SendMails @userids varchar(MAX), ), ), @c va ...
- TreeSet与TreeMap
TreeSet底层使用的存储容器为TreeMap TreeMap使用红黑树(一种自平衡的排序二叉树)实现,检索效率为O(logn) 红黑树的三个基本操作:左旋.右旋.着色 平衡二叉树:空树或左右子树高 ...
- svg text文字居中
<text x="100" y="100" text-anchor="middle" dominant-baseline=" ...