Написание простой функции puts()
/* original function prototype */ int puts(const char *s);
Функция puts()
позволяет записывать строку (строки) в стандартный вывод (stdout). Эта функция проще, чем функция printf()
, поскольку она не учитывает другие данные. сложности. Это только для печати строк.
Когда вы пишете свою собственную функцию, вы укрепляете свое понимание концепций программирования.
Для этой задачи нам понадобится библиотека C с именем unistd.h
. В этой библиотеке есть функция, которая нам понадобится для записивывода в любой поток ввода-вывода, который мы предпочитаем. Раз уж мы упомянули поток ввода-вывода, давайте кратко объясним, что это такое. Поток ввода-вывода — это просто абстракция, позволяющая манипулировать операциями ввода и вывода с последовательностью символов, например со строкой или файлом. Нас интересуют три потока: stdin, stdout и stderr. Давайте разберем их.
стандартный ввод (stdin) — это поток, который позволяет передавать на компьютер информацию; наиболее заметные операции – ввод с клавиатуры или чтение из файла. Он имеет уникальный номер, называемый номером файлового дескриптора (FDN). Номер дескриптора файла для стандартного ввода равен нулю (0).
Стандартный вывод (stdout) — это поток, который позволяет отправлять результаты на экран компьютера или даже в файл. Думайте об этом как о своем источнике вывода. Номер его файлового дескриптора равен 1.
Наконец, стандартная ошибка (stderr) — это место, куда отправляются все, как вы уже догадались, ошибки. Обычно вы видите ошибки на том же экране, что и ваш обычный вывод, но они используют разные потоки. Номер дескриптора файла stderr равен 2.
Теперь, когда мы понимаем, что такое потоки ввода-вывода, давайте перейдем к объяснению процесса написания нашей пользовательской функции puts()
function. Помните, мы пытаемся что-то показать пользователю, поэтому у нас есть два варианта. Либо отправьте его в stdout, либо в stderr, здесь мы рассмотрим оба варианта. Мы вызовем функцию, которая записывает в стандартный вывод echo()
и echo_err()
для той, которая записывает в стандартный вывод. Он примет строку в качестве аргумента и выведет ее в поток ввода-вывода в зависимости от того, какая функция вызывается.
Как говорилось ранее, нам нужна определенная функция в библиотеке unistd.h
library. Эта функция удачно названа просто write()
. Ему требуются три аргумента: дескриптор файла, указатель на буфер и общее количество записываемых байтов. У нас уже есть правильные номера файловых дескрипторов, и буфер будет содержать строку, которую мы хотим напечатать. Общее количество байтов будет соответствовать количеству символов в строке, которую мы печатаем. Для этого мы будем использовать специальную функцию с именем _len()
, чтобы получить длину строки.
Наши прототипы функций будут следующими:
#include <unistd.> /* our prototypes */ int echo(const char *s); /* to standard out */ int echo_err(const char *s); /* to standard error */ int _len(const char *s); /* get length of string */ /* the write function's prototype */ ssize_t write(int fd, const void *buf, size_t count);
Реализация echo()
функции
/* filename: echo.c */ #include <unistd.h> #include "main.h" /** * echo - write string to stdout * @s: string * Return: number of characters printed */ int echo(const char *s) { int i = _len(s); write(1, s, i); write(1, "\n", 1); return (i); }
Реализация echo_err()
функции
/* filename: echo_err.c */ #include <unistd.h> #include "main.h" /** * echo_err - write string to stderr * @s: string * Return: number of characters printed */ int echo(const char *s) { int i = _len(s); write(2, s, i); write(2, "\n", 1); return (i); }
Реализация функции _len()
/* filename: _len.c */ /** * _len - get length of string * @s: string * Return: string length */ int _len(const char *s) { int i = 0; for (; *s; s++, i++) ; return (i); }
Код драйвера для проверки нашего кода
Мы будем использовать этот код для тестирования наших функций. Это просто и это все, что нам для этого нужно.
/* filename: main.c */ #include "main.h" /* our function prototypes file */ /** * main - driver code to test functions * Return: 0 */ int main(void) { echo("Hello, world!"); echo_err("Oops, an error!"); return (0); }
Теперь, когда все готово, мы можем скомпилировать и запустить наш код. Хотя метод компиляции может отличаться, я использовал Makefile (номер 2).
Вывод, показанный на изображении выше, показывает, что функция работает правильно при первоначальном выполнении (номер 3). Ожидаемые результаты выводятся на экран, и хотя может показаться, что использовался только стандартный вывод, на самом деле функция использовала разные потоки ввода-вывода. При перенаправлении стандартного вывода (номер 4) появляется текст «К сожалению, ошибка!» отображается. Этот текст был включен в вызов echo_err()
функции. С другой стороны, когда stderr перенаправляется (номер 5), отображается текст «Hello, World», который был текстом, заданным при вызове функции echo()
. Цифры 6 и 7 показывают содержимое после перенаправления.
Надеюсь, это помогло вам понять некоторые концепции и то, как их можно объединить. Исходный код доступен в моей учетной записи GitHub. Доступ к нему по этой ссылке.