2013-06-05 287 views
2

我將從我的用例開始。我是一名老師,我有學生爲我編寫非常簡單的C++控制檯程序。我想通過爲他們的整個應用程序編寫測試工具來自動分級他們的程序。當他們使用cin請求輸入時,我想給它。當他們使用cout我想能夠解析他們的輸出正確的功能。我很確定我的老師在大學時爲我們做了這個。什麼是這樣的好方法?有沒有更好的方法來驗證他們的代碼比解析輸出?我應該解析他們的實際代碼並尋找函數聲明嗎?謝謝。編寫一個程序來運行另一個書面程序

+1

慶典將是可能最簡單的方法。如果您堅持使用C/C++,那麼首先您需要管道文件描述符,以便您可以通過自己的函數向其0(in)和1(out)文件描述符提供數據。 –

+2

請不要僅根據此自動過程的結果對它們進行分級。 –

+6

這是你的工作和職業責任,所以請親自去做:) – valdo

回答

0

你的問題是相當開放的,但你可能想要研究的一件事是C++系統命令。查看更多關於它的信息here

0

假設你要像Linux或MacOS的/ X,forkpty(一POSIX-Y OS在做這個)將做到這一點很容易地看到...下面的示例在子進程中運行「ping 127.0.0.1」,並在它讀取()的時候輸出ping進程的stdout輸出。你可以在同一個文件描述符上使用write()寫入子進程的stdin。

Windows下也有類似的技術,但按照傳統,它的難度和難度要大10倍左右。讓我知道這是你需要做的事情。

#include <stdio.h> 
#include <termios.h> 
#include <unistd.h> 

#if defined(__linux__) 
# include <pty.h>  // for forkpty() on Linux 
#else 
# include <util.h> // for forkpty() on MacOS/X 
#endif 

int main(int argc, char ** argv) 
{ 
    int fd; 
    pid_t pid = forkpty(&fd, NULL, NULL, NULL); 
    if (pid > 0) 
    { 
     // We're running in the parent process. We can now write to the child process 
     // (and read from it) via (fd). 
     while(1) 
     { 
     char buf[4096]; 
     int numBytesRead = read(fd, buf, sizeof(buf)-1); 
     if (numBytesRead > 0) 
     { 
      buf[numBytesRead] = '\0'; // ensure termination 
      printf("Read from child process's stdout: [%s]\n", buf); 
     } 
     else if (numBytesRead == 0) 
     { 
      printf("Child process exited\n"); 
      break; 
     } 
     else {perror("read"); break;} 
     } 
    } 
    else if (pid == 0) 
    { 
     // We're running in the child process. 

     // Turn off the echo, we don't want to see that back on stdout 
     struct termios tios; 
     if (tcgetattr(STDIN_FILENO, &tios) >= 0) 
     { 
     tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 
     tios.c_oflag &= ~(ONLCR); /* also turn off NL to CR/NL mapping on output */ 
     (void) tcsetattr(STDIN_FILENO, TCSANOW, &tios); 
     } 

     char * const argv[] = {"/sbin/ping", "-c", "5", "127.0.0.1", NULL}; // Replace /sbin/ping with your favorite program to run instead 
     if (execvp(argv[0], argv) < 0) perror("execvp"); 
    } 
    else if (pid < 0) perror("forkpty"); 

    return 0; 
} 
0

這似乎是單元測試的一個很好的用法。編寫一些頭文件,爲頭文件定義的函數編寫單元測試,然後給學生提供頭文件和單元測試,並在測試通過之前拒絕爲工作評分。爲了進一步減少你的時間浪費,讓他們編譯一切與-Wall -Werror

一旦測試通過,我會查看代碼以確保它們沒有做任何邪惡的事情,只是爲了讓測試通過。

我見過的C++最好的單元測試框架是Google Test。編寫起來很簡單,而且易於運行。

在另一方面,如果所有你關心的是輸入和輸出,只需要使用bash和管道:

#!/bin/bash 

for executable in * ; do 
    if cat input.txt | $executable | diff - expected-output.txt > /dev/null ; then 
     echo $executable passes 
    else 
     echo $executable fails 
    fi 
done