• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak używać testów do programów w c++ (.in/.out)

Object Storage Arubacloud
+2 głosów
359 wizyt
pytanie zadane 5 stycznia 2022 w C i C++ przez Dobdo Użytkownik (570 p.)
Cześć.

Czasami do programów (najczęściej tych konkursowych) tworzy się dedykowane pliki .in i .out, które zawierają dane wejściowe i poprawne wyjściowe. Posiadam akurat takie testy do pewnego algorytmu, który napisałem w C++. Czy istnieje jakiś łatwy i szybki sposób by te wszystkie dane z pliku .in wstawić do cin'ów w programie, które normalnie te dane biorą przez ręczne wpisanie do konsoli czy raczej trzeba bawić się w wczytywanie danych z pliku .in?

3 odpowiedzi

+3 głosów
odpowiedź 5 stycznia 2022 przez adrian17 Ekspert (344,860 p.)
wybrane 6 stycznia 2022 przez Dobdo
 
Najlepsza

`cin` to standardowe wejście - ale to nie musi znaczyć "wpisane ręcznie w konsoli".

Jak w konsoli odpalisz

moj_program < wejscie.in

To zawartość pliku będzie potraktowana, jakby została wpisana na wejście. Zadziała to na każdym systemie.

Podobnie, dodając

> wyjscie.out

Wyjście zostanie zapisane do pliku, a nie wyświetlone na konsolę.

komentarz 5 stycznia 2022 przez Dobdo Użytkownik (570 p.)
Nie wiem czy dobrze rozumiem. W folderze, w którym mam plik exe umieszczam plik z testem np. "test.in" i potem odpalam cmd/poweshella ze ścieżką do foldera z tym i wpisuję w nim: "nazwa_programu.exe < test.in"? Obecnie powoduje to błąd. W którym miejscu powinienem to wpisać?
komentarz 5 stycznia 2022 przez adrian17 Ekspert (344,860 p.)

Obecnie powoduje to błąd.

To nic nikomu nigdy nie mówi, musisz zawsze pisać jaki błąd.

komentarz 5 stycznia 2022 przez Dobdo Użytkownik (570 p.)
C:\---------------\Debug> program.exe < test1.in
At line:1 char:11
+ program.exe < test1.in
+           ~
The '<' operator is reserved for future use.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported

 

komentarz 5 stycznia 2022 przez adrian17 Ekspert (344,860 p.)
+1 głos
odpowiedź 5 stycznia 2022 przez Whistleroosh Maniak (56,980 p.)
edycja 5 stycznia 2022 przez Whistleroosh

Ja zawsze piszę sobie skrypt w bashu w którym robie przekierowanie strumienia wejściowego i wyjściowego, a następnie wczytuje wszystkie .in i porównuje wynik programu z odpowiednimi .out Nie wiem czy da się prościej. Tak wygląda ten skrypt:

#!/bin/bash

touch result.txt

for entry in "./in"/*
do
    prefix="./in/"
    sufix=".in"

    name=${entry#"$prefix"}
    name=${name%"$sufix"}
    
    file1="./in/${name}.in"
    file2="./out/${name}.out"

    echo $name
    ./main < $file1 > result.txt
       
    difference=$(diff -Z "result.txt" "$file2")
    if [ "$difference" != "" ]
    then
        echo "BAD"
        break
    else
        echo "GOOD"
    fi
done

Wszystkie pliki .in muszą być w folderze in, a wszystkie pliki .out muszą być w folderze out

 

0 głosów
odpowiedź 5 stycznia 2022 przez toko Dyskutant (7,670 p.)
edycja 5 stycznia 2022 przez toko

Nie znam niczego co by tak robiło, oprócz pisanych ręcznie bibliotek i programów. Ja używam swojego krótkiego programu (nie radzę używać przy dużym outpucie, bo wtedy trochę muli):

#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
bool isWhiteSpace(char c) {
	return (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\f');
}
bool isNumber(string str) {
	return !str.empty() && str.find_first_not_of("0123456789") == string::npos;
}
std::string itos(int value, int min_length = 1) {
        std::string result = std::to_string(value);
        reverse(result.begin(), result.end());
        while(result.size() < min_length) {
                result += "0";
        }
        reverse(result.begin(), result.end());
        return result;
}
int main(int argc, char* argv[])
{
	string program;
	string testspath = ".";
	string path = ".";
	int ile = 0;
	bool p = false;
	bool o = false;
	bool e = false;
	for(int i = 1; i < argc; i++) {
		if(string(argv[i]) == "-p")
			p = true;
		else if(string(argv[i]) == "-o")
			o = true;
		else if(string(argv[i]) == "-e")
			e = true;
		else if(string(argv[i]) == "-t" && i+1 < argc)
			testspath = argv[++i];
		else if(string(argv[i]) == "-d" && i+1 < argc)
			path = argv[++i];
		else if(isNumber(argv[i]))
			ile = atoi(argv[i]);
		else
			program = argv[i];
	}
	cout << "tester" << (p?" -p":"") << (e?" -e":"") << (o?" -o":"") << " -t "+testspath << " -d "+path << " " << ile << " "+program << endl;
	for(int i = 1; i <= ile && program.size(); i++) {
		string ii = itos(i /*, itos(ile).size()*/);
		system((program+" < "+testspath+"/in/test"+ii+".in > "+path+"/test"+ii+".out 2> "+path+"/test"+ii+".err").c_str());
		fstream file0(testspath+"/in/test"+ii+".in", ios::in);
		fstream file1(testspath+"/out/test"+ii+".out", ios::in);
		fstream file2(path+"/test"+ii+".out", ios::in);
		fstream file3(path+"/test"+ii+".err", ios::in);
		if(file0.good() && file1.good() && file2.good() && file3.good()) {
			string sp((istreambuf_iterator<char>(file0)), (istreambuf_iterator<char>()));
			string so1((istreambuf_iterator<char>(file1)), (istreambuf_iterator<char>()));
			string so2((istreambuf_iterator<char>(file2)), (istreambuf_iterator<char>()));
			string se((istreambuf_iterator<char>(file3)), (istreambuf_iterator<char>()));
			string po1 = so1;
			string po2 = so2;
			po1.erase(remove_if(po1.begin(), po1.end(), isWhiteSpace), po1.end());
			po2.erase(remove_if(po2.begin(), po2.end(), isWhiteSpace), po2.end());
			if(po1 == po2)
				cout << "\033[32m"+ii+": OK\033[39m\n";
			else
				cout << "\033[31m"+ii+": ZLE\033[39m\n";
			if(p) {
				cout << "Pytanie:\n" << sp << "\n";
			}
			if(o) {
				cout << "Poprawna odpowiedź:\n" << so1 << "\n";
				cout << "Odpowiedź:\n" << so2 << "\n";
			}
			if(e) {
				cout << "Błędy:\n" << se << "\n";
			}
		} else {
			cout << "\033[31m"+ii+": Nie można otworzyć plików!\033[39m\n";
		}
	}
}

argumenty:

  • ścieżka do programu (w takiej formie jak podajesz w konsoli przy uruchamianiu) (w przypadku niepodania program nic nie zrobi) (default "")
  • ilość testów (w przypadku niepodania program nic nie zrobi) (default 0)

opcjonalne argumenty:

  • -p - włącza wypisywanie pliku .in (default false)
  • -o - włącza wypisywanie pliku .out i odpowiedzi programu (default false)
  • -e - włącza wypisywanie błędów (standardowego wyjścia błędów) programu (dafault false)
  • -t "ścieżka do folderu z testami" - testy będą brane z lokalizacji "ścieżka do folderu z testami" (dafault ".")
  • -d "ścieżka do folderu z outputem programu na wszystkich testach" - odpowiedzi programu będą zapisywane w lokalizacji "ścieżka do folderu..." (default ".")

 testy numerowane od 1 do ilości testów, (test1.in, test2.in, test3.in ... test[ilość testów].in)

po odkomentowaniu pierwszej linii w forze, testy powinny wyglądać tak (zawsze numer tej samej długości):

test01.in, test02.in, test03.in, test04.in ... test15.in, test16.in

ułożone są wtedy w dobrej kolejności w przeglądarce plików.

Ponadto pliki wyjścia programu są zapisane w "[ścieżka do folderu z outputem...]/test[numer testu].[in i err]"

Przykładowe użycie: ./tester ./program -p -o -e -t testy -d odpowiedzi 50

PS. Zapomniałem dodać, że pliki .out powinny być w katalogu out a pliki .in w katalogu in.

Podobne pytania

0 głosów
0 odpowiedzi 89 wizyt
pytanie zadane 14 grudnia 2018 w C# przez marcin99b Szeryf (82,180 p.)
0 głosów
0 odpowiedzi 145 wizyt
+4 głosów
0 odpowiedzi 290 wizyt
pytanie zadane 17 lutego 2020 w Nasze projekty przez MysticRPG Nowicjusz (160 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...