V Открытая олимпиада школьников по программированию,
2010/11 учебный год
Олимпиада посвящена 100-летию со дня рождения Мстислава Всеволодовича Келдыша
Поскольку часто именно файловый ввод-вывод является основной проблемой начинающих участников олимпиад,
мы подготовили небольшую памятку, демонстрирующую реализацию ввода-вывода на различных языках программирования.
Программа на любом языке программирования должна завершаться с кодом возврата 0. В частности, программа на C всегда должна заканчиваться оператором return 0;
Имена входных и выходных файлов должны быть написаны маленькими латинскими буквами. Не забывайте закрывать выходной файл (иначе во многих языках он остается пустым).
Ввод-вывод будем демонстрировать на примере следующей задачи: в файле sum.in записаны два целых числа по модулю не превышающих 32000, в файл sum.out нужно вывести их сумму.
Примечание для программирующих на QBasic, Borland Pascal, Borland C: Жюри не гарантирует, что любую задачу олимпиады можно решить с использованием этих языков программирования.
Pascal, Delphi
Примечание для программирующих на Delphi: Имена стандартных модулей пишутся точно так же, как в документации (имеется в виду сочетание больших и маленьких букв) и только так. Например: Math, SysUtils.
var a,b:longint;
begin
assign(input,'sum.in');
reset(input);
assign(output,'sum.out');
rewrite(output);
read(a,b);
writeln(a+b);
close(input);
close(output);
end.
C
#include <stdio.h>
int main(void)
{
long a, b;
FILE *fin, *fout;
fin = fopen("sum.in", "r");
fout = fopen("sum.out", "w");
fscanf(fin, "%ld%ld", &a, &b);
fprintf(fout, "%ld", a + b);
fclose(fin);
fclose(fout);
return 0;
}
Примечание для программирующих на GNU C/C++: При выводе значений переменных типа long long под ОС Windows нужно использовать спецификатор %I64d, а при сдаче решений на проверку (для ОС Linux) - спецификатор %lld.
"Универсальный" код, который работает правильно под обеими системами, может выглядеть так:
#ifdef WIN32
printf("%I64d\n",ans);
#else
printf("%lld\n",ans);
#endif
C++
#include <fstream>
using namespace std;
int main ()
{
long a, b;
ifstream fin ("sum.in");
ofstream fout ("sum.out");
fin >> a >> b;
fout << a + b << endl;
fin.close ();
fout.close ();
return 0;
}
Java
Программа должна находиться в единственном классе с именем Main (обязательно с большой буквы), метод main должен находиться внутри класса Main. Вложенные классы допускаются.
import java.io.*;
public class Main
{
public static void main(String[] args) throws Exception
{
StreamTokenizer in = new StreamTokenizer(
new BufferedInputStream(
new FileInputStream(new File("sum.in"))));
PrintStream out = new PrintStream(new File("sum.out"));
int a, b;
in.nextToken(); a = (int) in.nval;
in.nextToken(); b = (int) in.nval;
out.println(a + b);
}
}
QBasic
open "sum.in" for input as #1
open "sum.out" for output as #2
input #1,a,b
print #2,a+b
close #1
close #2
perl, php, python, ruby
В скриптовых языках perl, php, python, ruby отсутствует возможность
потокового ввода данных, свойственного для языков Pascal, C и C++, то
есть в этих языках нельзя простыми методами считать из входного файла
последовательность целых чисел (действительных чисел, строк и т.д.),
если неизвестно, находятся ли эти числа в одной строке или в разных
строках.
Для ввода данных в этих языках предлагается считывать содержимое всего
файла сразу в строковую переменную, а затем использовать стандартную
функцию split для разбивки этой переменной на поля. Функция split
игнорирует все начальные и конечные пробельные символы (то есть
пробелы, символы табуляции и символы новой строки), а все прочие
символы разбиваются на последовательности, состоящие из непробельных
символов, пробельные символы являются разделителями для
полученных последовательностей. В результате получается список,
состоящий из строк непробельных символов, содержащихся в исходном
файле. Например, если в исходном файле записана строка "1 2 abc"
(количество пробелов неважно), то в полученном списке будет три
элемента - "1", "2" и "abc".
В языке php имеется небольшое отличие - функция называется preg_split,
при ее вызове в качестве аргумента необходимо явно указать регулярное
выражение, которое задает разделитель полей (это /\s+/, в языках perl,
python и ruby такое значение разделителя используется по умолчанию), и
перед вызовом функции preg_split необходимо явно удалить начальные и
концевые пробелы из строки функцией trim (в языках perl, python и ruby
это делает сама функция split).
Можно пользоваться и другими способами ввода-вывода данных,
поддерживаемых данными языками.
Ниже приведены примеры решения задачи "A+B" на языках perl, php, python, ruby.
perl
#!/usr/bin/perl -w
# Объявляем файлы FIN и FOUT для ввода-вывода данных
open(FIN, "<sum.in");
open(FOUT,">sum.out");
# В переменной $/ записан символ, который считается разделителем строк
# Удаление этой переменной приведет к тому, что весь файл будет считаться
# одной большой строкой.
undef $/;
# Считываем содержимое всего файла в переменную $_
$_=<FIN>;
# Разбиваем переменную $_ на поля по пробельным символам
# и записываем поля в список @InputData
my @InputData=split;
# Теперь в элементах списка $InputData[0] и $InputData[1]
# записаны два входных числа. Запишем их сумму в переменную $Answer
my $Answer=$InputData[0]+$InputData[1];
# Выведем результат в файл
print FOUT $Answer;
# Закроем файлы FIN и FOUT
close(FIN);
close(FOUT);
php
<?php
# Считываем весь файл при помощи функции file_get_contents,
# удаляем начальные и конечные пробелы при помощи функции trim
# результат разбиваем на поля функцией split по шаблону /\s+/,
# задающему последовательность пробельных символов в качестве разделителя
# и записываем результат в массив InputData
$InputData=preg_split('/\s+/', trim(file_get_contents('sum.in')));
# Теперь в элементах массива $InputData[0] и $InputData[1]
# записаны два входных числа.
# Запишем их сумму в переменную $Answer
$Answer=$InputData[0]+$InputData[1];
# Объявляем файл FOUT для вывода данных
$FOUT=fopen("sum.out","w");
# Выведем результат в файл FOUT
fputs($FOUT,$Answer);
# Закроем файл FOUT
fclose($FOUT);
?>
python
#!/usr/bin/python
# Объявляем файлы FIN и FOUT для ввода-вывода данных
FIN = open("sum.in", "r")
FOUT = open("sum.out", "w")
# Считываем весь файл при помощи метода read(),
# результат разбиваем на поля по пробельным символам методом split()
# и записываем в список InputData
InputData = FIN.read().split()
# Теперь в элементах списка InputData[0] и InputData[1]
# записаны два входных числа в виде строк.
# Преобразуем их к типу int и запишем их сумму в переменную Answer
Answer = int(InputData[0]) + int(InputData[1])
# Выведем результат в файл
print >> FOUT, Answer
# Закроем файлы FIN и FOUT
FIN.close()
FOUT.close()
ruby
#!/usr/bin/ruby
# Объявляем файлы FIN и FOUT для ввода-вывода данных
FIN = open("sum.in", "r")
FOUT = open("sum.out", "w")
# Считываем весь входной файл при помощи метода read(),
# результат разбиваем на поля по пробельным символам методом split()
# и записываем в список InputData
InputData = FIN.read().split()
# Теперь в элементах списка InputData[0] и InputData[1]
# записаны два входных числа в виде строк.
# Преобразуем их к целочисленному типу и запишем их сумму в переменную Answer
A=InputData[0].to_i
B=InputData[1].to_i
Answer=A+B
# Выведем результат в файл FOUT
FOUT.puts(Answer)
# Закроем файлы FIN и FOUT
FIN.close()
FOUT.close()
|