Используйте getopt()
или, возможно, getopt_long()
.
int iflag = 0;
enum { WORD_MODE, LINE_MODE } op_mode = WORD_MODE; // Default set
int opt;
while ((opt = getopt(argc, argv, "ilw") != -1)
{
switch (opt)
{
case 'i':
iflag = 1;
break;
case 'l':
op_mode = LINE_MODE;
break;
case 'w':
op_mode = WORD_MODE;
break;
default:
fprintf(stderr, "Usage: %s [-ilw] [file ...]\n", argv[0]);
exit(EXIT_FAILURE);
}
}
/* Process file names or stdin */
if (optind >= argc)
process(stdin, "(standard input)", op_mode);
else
{
int i;
for (i = optind; i < argc; i++)
{
FILE *fp = fopen(argv[i], "r");
if (fp == 0)
fprintf(stderr, "%s: failed to open %s (%d %s)\n",
argv[0], argv[i], errno, strerror(errno));
else
{
process(fp, argv[i], op_mode);
fclose(fp);
}
}
}
Обратите внимание, что вам нужно определить, какие заголовки должны включать (I сделайте 4, которые требуются), и способ, которым я написал тип op_mode
, означает, что у вас есть проблема в функции process()
- вы не можете получить доступ к перечислению там. Лучше всего переместить перечисление вне функции; вы можете даже сделать op_mode
переменную с файлом без внешней привязки (причудливый способ сказать static
), чтобы избежать передачи ее функции. Этот код не обрабатывает -
как синоним стандартного ввода, другое упражнение для читателя. Обратите внимание, что getopt()
автоматически выполняет --
, чтобы отметить конец опций для вас.
Я не запускал какую-либо версию ввода выше компилятора; в нем могут быть ошибки.
Для дополнительного кредита напишите функцию (библиотека):
int filter(int argc, char **argv, int idx, int (*function)(FILE *fp, const char *fn));
, которая инкапсулирует логику для обработки параметров имени файла после getopt()
. Он должен обрабатывать -
в качестве стандартного ввода. Обратите внимание, что использование этого будет означать, что op_mode
должно быть переменной статического файла. Функция filter()
принимает argc
, argv
, optind
и указатель на функцию обработки. Он должен вернуть 0 (EXIT_SUCCESS), если он смог открыть все файлы и все вызовы функции 0, иначе 1 (или EXIT_FAILURE). Наличие такой функции упрощает запись программ «фильтра» в стиле Unix, которые читают файлы, указанные в командной строке или стандартном вводе.
Ниже приведены пять вариантов достижения этого макета:
flex: 1
Применить position: relative
к контейнеру гибкого диска.
Применить position: absolute
к пункту D.
Теперь этот элемент абсолютно расположен внутри контейнера flex.
Подробнее , элемент D удаляется из потока документов, но остается в пределах ближайшего расположенного предка .
Используйте свойства смещения CSS top
и right
для перемещения этого элемента в положение
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Одно из предостережений в этом методе состоит в том, что некоторые браузеры могут не полностью удалить абсолютно позиционированный элемент гибкости из нормальный поток. Это изменяет выравнивание нестандартным, неожиданным способом. Подробнее: Абсолютно позиционированный элемент гибкости не удаляется из нормального потока в IE11
С комбинацией полей auto
и нового невидимого элемента гибкости макет может быть достигнут.
новый элемент гибкости идентичен элементу D и расположен на противоположном конце (левый край).
Более конкретно, поскольку выравнивание гибкости основано на распределении свободного места, новый элемент является необходимым противовесом для сохранения трех средних квадратов по горизонтали. Новый элемент должен иметь ту же ширину, что и существующий элемент D, или средние поля не будут точно центрированы.
Новый элемент удаляется из представления с помощью visibility: hidden
.
Короче:
D
. auto
, чтобы сохранить A
, B
и C
в центре, причем оба элемента D
создают одинаковый баланс с обоих концов. visibility: hidden
к дубликату D
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Этот метод аналогичен # 2, за исключением того, что он очищен семантически, и ширина D
должна быть известна.
D
. ::before
. auto
, чтобы сохранить A
, B
и C
идеально центрированы, причем элементы псевдо и D
создают одинаковый баланс с обоих концов.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
flex: 1
в левый и правый элементы Начиная с метода № 2 или № 3 выше, вместо того, чтобы беспокоиться о равной ширине для левой и правой правильные элементы для поддержания равного баланса, просто дайте каждому flex: 1
. Это заставит их обоих потреблять свободное пространство, центрируя средний элемент.
Затем вы можете добавить display: flex
к отдельным элементам, чтобы выровнять их содержимое.
ПРИМЕЧАНИЕ об использовании этого метода с min-height
: В настоящее время в Chrome, Firefox, Edge и, возможно, в других браузерах правило сокращения flex: 1
ломается до этого:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Этот процентный блок (%) в flex-basis
вызывает это метод прерывания, когда min-height
используется в контейнере. Это связано с тем, что, как правило, в процентах высоты для детей требуется явное свойство свойства height
для родителя.
Это старое правило CSS, относящееся к 1998 году ( CSS Level 2 ), который по-прежнему действует во многих браузерах в той или иной степени. Подробнее см. Здесь здесь и здесь .
Вот иллюстрация проблемы, опубликованной в комментариях пользователя user2651804 :
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Решение состоит в том, чтобы не использовать процентную единицу. Попробуйте px
или просто ничего (, что действительно рекомендует спецификация , несмотря на то, что по крайней мере некоторые из основных браузеров приложили процентную единицу по любой причине).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Это может быть самый чистый и эффективный метод. Нет необходимости в абсолютном позиционировании, поддельных элементах или других хакерах.
Просто создайте сетку с несколькими столбцами. Затем разместите свои позиции в середине и в конце столбцов. В принципе, просто оставьте первый столбец пустым.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>
Очень четкий вопрос. Я не мог не опубликовать ответ после нескольких часов рытья. Мы могли бы решить это с помощью таблиц, табличных ячеек, абсолютных позиций, преобразований, но нам просто нужно было сделать это с помощью flexbox:)
.parent {
display: flex;
justify-content: flex-end;
}
.center {
margin: auto;
}
min-width/min-height
для моего гибкого контейнера. Детиflex: 1
такого родителя не получают равную ширину / высоту. В любом случае? – user2651804 26 March 2018 в 09:45