LINUX.ORG.RU

Сим-сим, откройся

 , , , ,


0

1

Развивая темы предыдущих исследований-уроков начинающим от начинающих и опытных

пришла мысль такого следующего творческого задания:

Написать такую программу в файл, чтобы она этот файл и отобразила. То есть: показала саму себя в исходном виде (коде).

Ну и, как и прежде напоминаю: в приоритете ясность, понимаемость, наглядность, лёгкость восприятия. Это не гольф-кодинг и не соревнование на краткость! Но минимализм - получается как следствие, чтобы убрать лишнее в коде. Как говорится: чтобы «за деревьями увидеть лес».

Отступлю от своего предыдущего опыта и переключусь с классического Си на оболочку Борна:

#!/bin/bash
while read l; do echo $l; done < $0
# такая нехитрая программа

Трёхстрочник из:

  1. Ши-бенг сигнатура оболочки (в классике /bin/sh)
  2. Собственно интерпретируемый рабочий код - только из встроенных (builtin) команд bash: while..do..done, read, echo. Т.е. никаких внешних программ не просим. Получается цикл, где в условии одновременно с проверкой на возможность чтения из потока - в переменную l загоняется очередная строка этого самого потока. А он в свою очередь является переадресованным (<) вводом из самого файла со скриптом ($0). В теле цикла echo итеративно выводит на экран значение ($) переменной l.
  3. финальный, не исполняемый комментарий тоже начинается с решётки, но будет показан нашим конкретным скриптом при запуске («самопрезентации»).

Ставим права и запускаем наш скрипт в файле selfie.sh:

chmod u+x selfie.sh
./selfie.sh

P.S.

Если меня не опередят: планирую написать нечто аналогичное на Си (как и в прошлый раз). Отображать и исходник, и бинарник. Но показывать читаемые символы (ASCII) исполнимого файла . То есть обложу себя условиями - никакого Unicode; исполнимый файл - с тем же именем, что и исходный, но без расширения (*.c).


Вы уже второй раз демонстрируете, что не понимаете разницу между bash и общепринятым распространенным набором того, что умеет shell-ы, скажем по posix. У вас не bash вовсе. Вот bash:

#!/usr/bin/env bash
IFS= read -d '' -r -a file < "$0"
printf "%s" "${file[@]}"
Ну и вот вам тест, ломающий вашу «программу», добавьте в конец:
echo << EOF
 test broken first space
-n
 complex \
 line
EOF

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)

Написать такую программу в файл, чтобы она этот файл и отобразила. То есть: показала саму себя в исходном виде (коде).

$ ./script 
#!/bin/cat
$
im-0
()

То есть: показала саму себя в исходном виде (коде).

> ./test.ps1

$MyInvocation.MyCommand.ScriptBlock

>
anonymous
()

пришла мысль такого следующего творческого задания

Где в тэгах quine, куайн, квайн, крошка Цахес?

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 3)

Написать такую программу в файл, чтобы она этот файл и отобразила. То есть: показала саму себя в исходном виде (коде)

Товарища @luke, всё равно уже никому не переплюнуть. Смысл?

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Там код довольно плохой, я думаю можно оптимальнее.

И ещё @beastie хочет поменять big-endians на little-endians.

luke ★★★★★
()
[georgii@snake tests]$ ./a.out 
#include <stdio.h>

int main() {
    FILE* f = fopen("lor.c", "r");
    if(!f) {
        printf("fucked up");
        return -1;
    }

    char buf[100];
    while(fgets(buf, 100, f) != NULL) {
        printf("%s", buf);
    }
}
snake266 ★★
()
Ответ на: комментарий от vvn_black

Это же будет 4.2, в квайнах нельзя читать свой файл. Здесь просто спецолимпиада по чтению своего исходника пока :/

cdshines ★★★★★
()

пришла мысль

Гениальная мысль, чо.

Вот тебе код на руби, который генерирует код на scala, который генеринует код на scheme, который генерирует код на шелле, который <40 языков пропущено>, который генерирует код на питоне, который генерирует код на R, который генерирует код на REXX, который генерирует исходный код на руби.

https://github.com/mame/quine-relay/blob/master/QR.rb

project
()
Ответ на: комментарий от snake266
write=1
exit_group=231
STDOUT_FILENO=1
.globl _start
.text
_start:
mov $siz,%edx
mov $str,%rsi
mov $STDOUT_FILENO,%edi
mov $write,%eax
syscall
mov $exit_group,%eax
syscall
.section .data.rel.ro
str:.incbin "tst.s"
siz=.-str



as -o1 tst.s &&ld 1 &&./a.out
anonymous
()

Ненавижу когда названия тем не отражают содержимого вопросов. Вроде даже в правилах форума было, обычно есть

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от project

40 языков пропущено

всего там их 128. после такого вот гиперквайна как-то и желание всё пропало. интересно, там уроборос во всех исходниках присутствует?

anonymous
()

Не совсем то, но я подобное иногда в отладке использую. Редко но есть такое.

#include <stdio.h>

#define repeat(func) const char * f = #func; func;

repeat(
int main()
{
    printf("%s\n",f);
    return 0;
});
dron@gnu:~$ gcc some.c ;./a.out 
int main() { printf("%s\n",f); return 0; }
dron@gnu:~$ 
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от anonymous

Когда ты о языке ни разу не слышал, а какой-то наркоман уже встроил его в квайн.

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

Вот это магия! Я даже на секунда округлил глаза. Мне просто в голову никогда не приходила мысль (да и нужды в этом не было) запихивать функцию в макрос.

snake266 ★★
()
Ответ на: комментарий от LINUX-ORG-RU

Кстати, в задании указано отобразить файл с кодом, а не функцию :). Но пример использования макроса классный, надо будет запомнить.

snake266 ★★
()
Ответ на: комментарий от snake266

Мне просто в голову никогда не приходила мысль (да и нужды в этом не было) запихивать функцию в макрос.

И не будет у тебя в этом нужды никогда, по крайней мере, в том виде, в котором привел @LINUX-ORG-RU – вся функция скукожится в одну длинную строку, поэтому это

я подобное иногда в отладке использую

сразу вылетает в трубу – list main или же gdbtui здесь сам доктор прописал, а не эти костыли.

Единственное, где это реально может пригодиться, так эти при «инъекции» GLSL-шейдеров (или чего другого) прямо в код на C:

static const char mainVS[] =
GLSL(
	layout(location = 0) in vec2 pos;

	void main()
	{
		gl_Position = vec4(pos, 0.0f, 1.0f);
	}
);

Но опять же – код шейдера склеивается в одну строку, что ухудшает (не то слово) отладку.

anonymous
()
Ответ на: комментарий от snake266

отобразить файл с кодом

Ну эт легко

#include <stdio.h>
#include <linux/limits.h>
int main(int argc, char *argv[])
{
    /*Комментарий*/
    char s[PATH_MAX]={0};
    printf("%lu\r%s",fread(s,1024-1,1,fopen(__FILE__,"r")),s);
    return 0;
}
dron@gnu:~$ gcc ccc.c 
dron@gnu:~$ ./a.out 
#include <stdio.h>
#include <linux/limits.h>
int main(int argc, char *argv[])
{
    /*Комментарий*/
    char s[PATH_MAX]={0};
    printf("%lu\r%s",fread(s,1024-1,1,fopen(__FILE__,"r")),s);
    return 0;
}
dron@gnu:~$ 

Можно ещё чтобы ./a.out открыл файл ./a.out нашёл там имя своего исходника и открыв уже его вывел на экран. Но эт лень делать.

UDP: 1024 надо на PATH_MAX-1 менять, а и хрен с ним, проверок тоже нет. Перл короче :D

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от anonymous

С расширениями gcc или юзая c++ для компиляции можно юзать raw чё-то там вот так

шейдер в отдельном файле

R"(
layout(location = 0) in vec2 pos;

void main()
{
    gl_Position = vec4(pos, 0.0f, 1.0f);
})"

сишка

#include <stdio.h>

int main(int argc, char *argv[])
{
    const char default_shader[] =
    {
        #include "shader.fs"
    };

    printf("%s\n",default_shader);
}

выхлоп

dron@gnu:~$ gcc ccc.c 
dron@gnu:~$ ./a.out 

layout(location = 0) in vec2 pos;

void main()
{
    gl_Position = vec4(pos, 0.0f, 1.0f);
}
dron@gnu:~$

Плюсы

  • 1 Сохраняется форматирование
  • 2 Автоматическое встраивание шейдера в код во время сборки
  • 3 Шейдер это отдельный файл, просто удобно редактировать

Минусы

  • R"(text)" не позволит юзать шейдер как загружаемый файл, но если загружаем можно вырезать R"( в начале и )" в конце и всё, далее слинковать шейдер.

  • После линковки шейдера который вшит, сам текст шейдера больше не нужен, но выгрузить его никак ибо он вшит + пару килобайт может быть памяти всё это займёт. Сомнительный минус, но всё же =)

По итогу. Можно иметь по умолчанию вкомпиленый в код шейдер автоматически забираемый во время сборки, не надо лезть в сишный исходник что-бы его править, при надобности можно изменить и перезагрузит тот же самый шейдер уже из файла, а если что не так сбросить на железно работающий из исходника. Довольно таки удобно. В релизной игре /софтине можно текстовые шейдеры выкинуть вообще ибо они и так уже вшиты.

UDP: Не fs а vs. =)

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Ну эт легко

Типичный сижник – «легко» ему, а в трех строках взял да запутался. Если у тебя файл больше чем PATH_MAX-1, то твоя программа сразу развалится на этом хелловорлде.

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(void)
{
	const int fd = open(__FILE__, O_RDONLY);
	struct stat fst;
	fstat(fd, &fst);
	const void *fp = mmap(0, fst.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	write(STDOUT_FILENO, fp, fst.st_size);
}
anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

щас бы не использовать ARB_gl_spirv в 2020…

выгрузить его никак

офигительные истории, расскажи это свопу

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

А потом ты узнаешь про такое понятие, как минификация glsl, и вся твоя схема пойдет крахом, плюс редактирование вкомпиленных шейдеров будет вызывать перекомпиляцию модуля, в который они включены, там у людей уже давно runtime-compiled C/C++, а форумные сижники все стремятся в каменный век уйти.

В релизной игре /софтине можно текстовые шейдеры выкинуть вообще ибо они и так уже вшиты.

И много ты таких уже «релизных игр» выпустил, или просто теоретик?

anonymous
()
Ответ на: комментарий от anonymous

Ты вшиваешь текст шейдера в исходник сишный в виде статического массива на этапе компиляции. free() на него ты не сделаешь. Я про это. А не про что-то там. Про явное, а не неявное. Пусть там OS химичит как ей надо.

щас бы не использовать ARB_gl_spirv в 2020

Я тебе OGL 4.6 в системе своей рожу чтоль? :D OpenGL2.1 Фарева GLSL 120 наше всюо… Другого нема у мну

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

Использовать PATH_MAX для буфера файла это такой brain fart конечно, но юным сижникам простительно, со всеми бывает.

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

С расширениями gcc или юзая c++ для компиляции можно юзать raw чё-то там вот так

И для справки, я знал, что ты это знаешь, я изначально писал это персонажу @snake256, который назвал эти макро-костыли магией. От тебя же я просто хотел услышать, как та нечитабельная однострочная простыня помогает тебе в отладке.

anonymous
()
Ответ на: комментарий от anonymous

Ты чёт вообще не в теме треда, тот анон предложил вшивать шейдеры, но мол отладочные сообщения будут в кашу, я ему ответил что можно тоже самое, но альтернативно с сохранением форматирования. А ты тут притензии какие то развёл. Тут фанимся, а не вопросы решаем или метадологии строим.

минификация glsl

Нафейхуя?

плюс редактирование вкомпиленных шейдеров будет вызывать перекомпиляцию модуля

Про const char почитай.

в который они включены, там у людей уже давно runtime-compiled

У большинства людей компиляция шейдеров во время запуска 1 раз. Меса кеширует шейдеры сама (если я не путаю) , а glShaderBinary завезли начиная с 4.1 я на 2.1 пишу. Мне с головой на мои поделки хватает.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Нафейхуя?

Я смотрю ты совсем слаб, ну сам подумай зачем минимизировать расход памяти на шейдеры, если у тебя их сотни (или сколько их там у Unity):

https://aras-p.info/blog/2016/09/01/SPIR-V-Compression/

плюс редактирование вкомпиленных шейдеров будет вызывать перекомпиляцию модуля

Про const char почитай.

facepalm.rs

// file.c
static const char vs[] =
{
    #include "shader.vs.glsl"
};
// другой код
touch shader.vs.glsl

Ouch, теперь надо пересобрать и file.c, я думал тебе это и так понятно.

У большинства людей компиляция шейдеров во время запуска 1 раз.

Так при разработка это как раз и неудобно, нужно чтобы ты в дебаге мог без перезапуска программы отредактировать шейдер и увидеть изменения, люди уже давно делают это даже с обычным C-кодом, погугли runtime-compiled C++, hot reload

https://ourmachinery.com/post/dll-hot-reloading-in-theory-and-practice/

anonymous
()
Ответ на: комментарий от anonymous

как та нечитабельная однострочная простыня помогает тебе в отладке.

Аааа. Ну я сказал что редко использовал, пердолился с другим макросом и в отладке разворачивал его через такой :D

Типа такого, давно было, шаблон генерировал функцию и структуру и что-то шло не так. через cpp src.c смотреть на кашу было невозможно

#include <stdio.h>

//bug macro
#define MACRO1(bla,bli,blu) int bla##bli = blu;

//debug macro
#define TOSTR(bla) #bla 
#define MACRO2(bla) printf("%s\n", TOSTR(bla));


int main(int argc, char *argv[])
{
    MACRO2( 
            MACRO1(ladfdla,tadssta,11)
            MACRO1(lasfsla,taddfta,13)
            MACRO1(laldffa,tadfdta,12)
            MACRO1(laldsfa,tdsfata,16)
            MACRO1(lalsdfa,tatdfda,10)
            )
    return 0;
}
LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от anonymous

минимизировать расход памяти на шейдеры

Код шейдера читается 1 раз, компилится 1 раз и линкуется 1 раз, более он не нужен. Пробелы, переносы строк и прочее роли не играют как и не играют роли для тех же сишных исходников к примеру когда они стали объектными файлами.

если у тебя их сотни (или сколько их там у Unity):

Олё, у меня обычный glsl у юньки там пишется шаблон который уже перегенерируется в нормальный шейдер. Как и у годота и прочих, там по сути пишешь для препроцессора который уже собирает всё.

SPIR-V

Я уже сказал что у меня OpenGL2.1 в использовании и GLSL# 120 стодвадцатой версии/ Нет тут SPIR-V никакого и нет бинарных GLSL модулей.

Ouch, теперь надо пересобрать и file.c, я думал тебе это и так понятно.

Я как бы в курсе. И анон выше тоже. Суть в том что у тебя может быть вшит готовый шейдер не нуждающийся более в правках а на этапе разработки ты можешь юзать его же из внешнего файла перезагружая при изменении.

Так при разработка это как раз и неудобно, нужно чтобы ты в дебаге мог без перезапуска программы отредактировать шейдер и увидеть изменения

Ну так и увидишь, повторю. Вшиваем шейдер в исходник в готовой программе, во время разработки источник шейдера выбираем из файла , при изменении перезагружаем его. Блин ща видос свой найду, я там просто изменяю шейдер и перезагружаю его когда мне надо без перезапуска программы https://youtu.be/FUYzaYnRJWY?t=151 Разве что у меня при этом пролаг, но это потому что я вместо перелинковки 1 шейдера ещё и текстуры перезагружал

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я уже сказал что у меня OpenGL2.1 в использовании и GLSL# 120 стодвадцатой версии/ Нет тут SPIR-V никакого и нет бинарных GLSL модулей.

Так и знал, что ты сагришься на этот SPIR-V, ты же даже не читаешь, что тебе дают на блюде:

SPIR-V were “fattest” by a large amount (DX9 and minified GLSL being the smallest)

Код шейдера читается 1 раз, компилится 1 раз и линкуется 1 раз, более он не нужен.

Вот люди глупые, минифицируют glsl, сжимают spirv, тут @LINUX-ORG-RU с сайта LINUX.ORG.RU все разрулил, сказал «Нинужна!»

Почитай, что может делать минификатор glsl, а потом говори:

https://web.archive.org/web/20171030145857/http://www.ctrl-alt-test.fr/?page_id=7

Поэтому твое это

Вшиваем шейдер в исходник в готовой программе

по-нормальному делается через отдельный этап сборки в release, который предварительно обрабатывает (минифицирует, или еще что) шейдер и уже потом #include’ит его в твою портянку. Плюс подобный этап сборки все равно понадобится для вулкана, например, только там будет glslang и еще какие-то твои нашлепки. Нет, в хелловорлдах, может, конечно можно обойтись и без этого, но я изначально говорил, что если углубиться, то твой путь с макросами-портянками не такой уж и оптимальный, я, думаю в этом ты можешь со мной согласиться.

anonymous
()
Ответ на: комментарий от anonymous

я, думаю в этом ты можешь со мной согласиться.

Не на 100% ибо во вшивании сорцов шейдера с другие сорцы не вижу фаталом. Но эту хрень я описал как возможность, сам же да, не использую такое (пока что по крайней мере). Шейдеры у меня отдельно лежат ибо играюсь я часто и вшивать пока нет смысла, а может и не будет никогда ибо за пределы моего компа редко уходят сырцы разве что то что на видосе можно в демке Corange взять на гитхабе. Ну и ещё парочку хернюшек там же.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Не на 100%

А на 100% и не надо, главное, чтобы мне удалось посеять некое зерно сомнения, зерно любопытства, чтобы тебе хотя бы отчасти стала понятна мотивация людей, которые используют этот подход. И потом через время и сам захочешь замутить что-то эдакое, и вспомнишь того ненормального анонима, который тебе тут пол-утра затирал что-то про «правильный» подход.

anonymous
()

Пустой shell-скрипт печатает самого себя:

$ echo -n > empty.sh
$ chmod a+x empty.sh 
$ ./empty.sh 
$
No ★★
()
Ответ на: комментарий от anonymous

Ну что вы так про сурово про костыли, программирование в некоторой степени магия.

snake266 ★★
()
Ответ на: комментарий от I-Love-Microsoft

Гуманитарии vs технари

Ненавижу когда названия тем не отражают содержимого вопросов. Вроде даже в правилах форума было, обычно есть

Как трудно гуманитариям понимать технарей. Вы Евангелие читали?

А там сказано:

Не человек для субботы, но суббота для человека.

Так и с правилами: ну нельзя всё воспринимать буквально… Вы включите воображение. И тогда понятно всё будет. Или настолько кровавый энтерпрайз поработил, что всё должно быть буквально и дословно и безо всяких там образов, метафор, притч…?

А иначе - это какое-то буквоедство и фарисейство получится…

Android
() автор топика
Ответ на: комментарий от teod0r

Содержимое файла в командную строку

printf '%s\n' "$(< "$0")"

Интересно получается: Теодор, ты во второй аргумент команды printf целиком включаешь содержимое файла. Что подтверждает включение отладки:

./selfie.sh 
+ printf '%s\n' '#!/bin/bash -x
printf '\''%s\n'\'' "$(<$0)"

# Скромный скрипт'

Мои эксперименты с экранированием двойными кавычками давали тоже занятные эффекты : содержимое распылалось пробелами по аргументам printf без них…

Надо комменты давать, а то пуристы могут захейтить…

Но для меня: принимается - тоже вариант использования встроенной команды и краткость.

А оператор $( выражение ) - это было в старом добром bourne shell , или в bash появилось?

Я всегда обратными кавычками `выражение` пользовался для подстановок вывода в текст строк.

Android
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Хочется понимаемей на Си

Спасибо за с юности учимую константу Си __FILE__ . Всё забывается…

Но зачем так усложнять, засовывая в printf и чтение функцией fopen, чтобы потом перетирать ещё выведенное значение длины файла, пользуясь символом возврата каретки \r ? Строк текста меньше. Но это уже получается искусство гольф-кодинга на тему минимума строк, или разделителей выражений-операторов с ;… Примеры усложняются…

Керниган и Ритчи в книге читают тексты посимвольно. Но мне захотелось построчно. Пример не такой краткий - но воспринимаемо понятней, надеюсь:

#include <stdio.h>
#define MAX_BUF 1024

int main(){
        char buf[MAX_BUF];
        FILE* f =fopen(__FILE__ , "r");
        if(!f){
                perror("Unable to open myself \"" __FILE__ "\"");
                return -1;
        }
        while(fgets(buf, MAX_BUF-1, f))
                puts(buf);
        return 0;
}
Android
() автор топика
Ответ на: Содержимое файла в командную строку от Android

А оператор $( выражение ) - это было в старом добром bourne shell , или в bash появилось?

не знаю, я думаю это давно

Я всегда обратными кавычками `выражение` пользовался для подстановок вывода в текст строк.

скобки позволяют делать вложенность $() внутри, и нет проблем с экранированием

teod0r ★★★★★
()
Ответ на: комментарий от anonymous

тут не нужна. но я везде $() использую, это для меня как стандарт

teod0r ★★★★★
()

Хернёй какой-то занимаетесь, граждане. Вот вам код, который выводит сам себя без всяких чтений файла

->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
anonymous
()

То есть просто прочитать файл и вывести на экран? Зачем столько буков для такого простого задания? Вот если исходника неет, вот это уже челлендж уровня лор.

anonymous
()
Ответ на: комментарий от anonymous

Самофильтр

То есть просто прочитать файл и вывести на экран? Зачем столько буков для такого простого задания? Вот если исходника неет, вот это уже челлендж уровня лор.

Вот это да - челендж. Начинайте новую тему. Знаю, что народ захочет постить вызов утилиты strings на себя. Но такого тривиального решения не надо. Надо показать будет как конкретный язык выражает фильтрацию печатных символов сам, без сторонних вызовов. Т.е. и без библиотек желательно.

Android
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.