LinuxForum.Fans
Тема

tcc или скрипты на ansi C

Автор: drBatty 19 сообщений 4113 просмотров
22.11.2014 03:35 #401977

Иногда нужно написать скрипт, для которого возможностей bash'а не хватает. С другой стороны, использование нормального ЯП тоже не оправдано. К примеру, bash не умеет арифметику с вещественными числами(только целые), ну или bash не умеет работать с отдельными символами(как с байтами. Точнее умеет, но работать с символами неудобно).

Можно использовать обычный ЯП C, стандарта C99, и интерпретатор/компилятор tcc.

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

text
#!/usr/bin/tcc -run

#include <stdio.h> #include <libgen.h> #include <stdlib.h> #include <string.h> #include <errno.h>

int main(int argc, char* argv[]) { const char* myname = basename(argv[0]); if(argc!=2) { fprintf(stderr, "Usage: %s FILENAME\n", myname); return 1; } int freq[256]; int j; for(j=0; j<256; j++) freq[j] = 0;

FILE* fs = fopen(argv[1], "r"); if(!fs) { fprintf(stderr, "%s:Can't open file '%s' (%s)\n", myname, argv[1], strerror(errno)); return 1; }

int c; while((c = fgetc(fs))!=EOF) freq[c]++; fclose(fs);

double sum = 0.0; for(j=0; j<256; j++) sum += freq[j]; if(sum==0.0) { fprintf(stderr, "%s:File '%s' is empty\n", myname, argv[1]); return 1; }

for(j=0; j<256; j++) if(freq[j]>0) printf("%d\t%c\t%d\t%f%%\n", j, j<=32 || j>=128? ' ': j, freq[j], (freq[j]/sum)*100); return 0; }

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

Показать
[console]$ ./wcf.c wcf.c
9 66 7.603687%
10 51 5.875576%
32 62 7.142857%
33 ! 4 0.460829%
34 " 10 1.152074%
35 # 6 0.691244%
37 % 12 1.382488%
39 ' 7 0.806452%
40 ( 21 2.419355%
41 ) 21 2.419355%
42 * 4 0.460829%
43 + 9 1.036866%
44 , 15 1.728111%
45 - 1 0.115207%
46 . 7 0.806452%
47 / 4 0.460829%
48 0 13 1.497696%
49 1 8 0.921659%
50 2 7 0.806452%
51 3 1 0.115207%
53 5 4 0.460829%
54 6 4 0.460829%
56 8 1 0.115207%
58 : 4 0.460829%
59 ; 24 2.764977%
60 < 9 1.036866%
61 = 15 1.728111%
62 > 7 0.806452%
63 ? 1 0.115207%
65 A 1 0.115207%
67 C 1 0.115207%
69 E 4 0.460829%
70 F 4 0.460829%
73 I 2 0.230415%
76 L 2 0.230415%
77 M 1 0.115207%
78 N 1 0.115207%
79 O 1 0.115207%
85 U 1 0.115207%
91 [ 12 1.382488%
92 \ 7 0.806452%
93 ] 12 1.382488%
97 a 18 2.073733%
98 b 5 0.576037%
99 c 18 2.073733%
100 d 13 1.497696%
101 e 39 4.493088%
102 f 30 3.456221%
103 g 11 1.267281%
104 h 8 0.921659%
105 i 28 3.225806%
106 j 19 2.188940%
108 l 12 1.382488%
109 m 15 1.728111%
110 n 38 4.377880%
111 o 12 1.382488%
112 p 7 0.806452%
113 q 7 0.806452%
114 r 49 5.645161%
115 s 27 3.110599%
116 t 28 3.225806%
117 u 16 1.843318%
118 v 5 0.576037%
119 w 1 0.115207%
121 y 5 0.576037%
123 { 4 0.460829%
124 | 2 0.230415%
125 } 4 0.460829%
[/console]
22.11.2014 05:12 #401982

Да есть Perl, Python...

В питоне можно использовать SQL запросы к БД...

22.11.2014 06:32 #401983

спасибо, познавательно, но я тоже, когда не хватает баша, просто нерехожу на пайтон.

22.11.2014 15:34 #401999

Ещё есть tk/tcl. Tcl - мощный shell-like interpreter.

Пётр.

23.11.2014 03:49 #402055

"Bif" написал:
Да есть Perl, Python...
это всем и без вас известно. Я видел тонны быдлокода и на том и не другом.

"Bif" написал:
В питоне можно использовать SQL запросы к БД...
ха! Удивили! Я на sed делал запросы к СУБД. Надо будет, сделаю под brainfuсk.

"Peter" написал:
Ещё есть tk/tcl. Tcl - мощный shell-like interpreter.
и что? Есть ещё Over9000 не менее "мощных" ЯП. А теперь расскажите, зачем это ваше не нужно вы юзаете?
23.11.2014 06:08 #402067

Спасибо, интересное решение.

dyasny написал:
нерехожу на пайтон.

А я его не знаю, но учить придется. Потому что на нем blueman написан, и из него надо выпилить обязательную поддержку пульсы.

23.11.2014 06:46 #402071
"yars" написал:
А я его не знаю, но учить придется. Потому что на нем blueman написан, и из него надо выпилить обязательную поддержку пульсы.

довольно простой и удобный язык, особенно если невыеЖиваться и не вдаваться в пайтонизмы. Особенно хорош тем что сама структура синтаксиса заставляет писать читабельный код. Я сейчас похоже буду Go учить, хотя предпочел бы не распыляться

23.11.2014 07:06 #402072

"dyasny" написал:
когда не хватает баша, просто нерехожу на пайтон.
ну питон это конечно хорошо, вот только C он быстрее будет. Всегда ведь можно просто взять, и собрать данный скрипт с помощью gcc. А питон так на всегда питоном и останется.

Есть ещё плюс: возможность нативного использования библиотек. Zlib, OpenSSL например. А в питоне оно на костылях, увы.

"dyasny" написал:
Особенно хорош тем что сама структура синтаксиса заставляет писать читабельный код.
быдлокодер и на питоне быдлокод писать будет. Это не лечится.
23.11.2014 07:29 · отредактировано #402073
"drBatty" написал:
ну  питон это  конечно  хорошо, вот только  C он  быстрее будет. Всегда  ведь  можно просто  взять, и  собрать данный  скрипт с  помощью  gcc. А питон так на всегда питоном и останется.

когда его не достаточно можно и на С, но я RT не пишу, в основном автомацию всякую

"drBatty" написал:
Есть ещё  плюс: возможность нативного использования  библиотек. Zlib, OpenSSL  например. А в питоне  оно на костылях, увы.

костыли под капотом - вполне возможно. но в написании все очень удобно, под все есть библиотеки

23.11.2014 08:19 #402085

"dyasny" написал:
когда его не достаточно можно и на С
ну а тут _сразу_ на C.

"dyasny" написал:
но я RT не пишу
тут как получится. Никогда не знаешь, где и когда быстродействия не хватит.

Смысл сабжевых скриптов в том, что их не придётся переписывать на C, т.к. они и так на C.

"dyasny" написал:
костыли под капотом - вполне возможно. но в написании все очень удобно, под все есть библиотеки
ну лично мне всё равно нужно знать , как работать с библиотеками на C/C++. А изучать биндинги X→Y мне лениво, т.к. ЯП я знаю около полусотни, а всяких Y и того больше. И везде свои сложности. В этих ваших питонах всяких например традиционная проблема с UTF-8, а ещё проблема версий(perl6, python3, и т.п.).
23.11.2014 08:29 #402089
"drBatty" написал:
ну  а  тут  _сразу_  на  C.

обычно его достаточно. не хватает не потому что функционала ЯП мало, а потому что надо работать не с объектами а с памятью напрямую например. Недавно как раз понадобился в срочном порядке прокси для бинарного потока, на пайтоне тормозило, сделали вставку которая читала из сокета в буфер, а потом писала в другой сокет на C. Вышло быстрее, да. Потом подумали еще раз и написали на пайтоне управлялку для iptables - оказалось еще быстрее

"drBatty" написал:
тут  как  получится.  Никогда не знаешь, где и когда  быстродействия  не хватит.
Смысл сабжевых скриптов  в том, что их не придётся  переписывать на C,  т.к.  они и так на C.

ну за то я и поблагодарил - добавил себе инструмент на всякий пожарный. Буду ли я его использовать повседневно - врядли, не те задачи

"drBatty" написал:
ну  лично  мне  всё равно  нужно знать , как работать с библиотеками на C/C++. А изучать биндинги  X→Y  мне  лениво,  т.к.  ЯП я  знаю около  полусотни, а  всяких Y и того больше. И везде свои сложности.  В этих  ваших  питонах всяких  например  традиционная проблема с UTF-8,  а ещё проблема  версий(perl6, python3,  и  т.п.).

везде свои проблемы, и все зависит от задач. C теряет смысл когда быстродействие не важно, зато надо писать большое количество сложного высокоуровневого функционала. Чтоб далеко не ходить - openstack отличный пример. Если бы его писали на С, его бы до сих пор не существовало.

23.11.2014 09:32 #402097

"dyasny" написал:
не хватает не потому что функционала ЯП мало,
дык почти все ЯП тьюринг-полные, даже на brainfuсk'е можно писать что угодно.

"dyasny" написал:
везде свои проблемы, и все зависит от задач. C теряет смысл когда быстродействие не важно, зато надо писать большое количество сложного высокоуровневого функционала. Чтоб далеко не ходить - openstack отличный пример. Если бы его писали на С, его бы до сих пор не существовало.
ну я вообще-то про короткие скрипты говорил.

Что до openstack, то его в принципе и сейчас не существует IRL. Это проект ИМХО.
Ну и потом, не вижу причин, почему проект нельзя было реализовывать на C++ с STL? Оно достаточно функциональное и высокоуровневое для таких целей.
23.11.2014 10:04 #402102

drBatty написал:

[quote="Peter"]Ещё есть tk/tcl. Tcl - мощный shell-like interpreter.
и что? Есть ещё Over9000 не менее "мощных" ЯП. А теперь расскажите, зачем это ваше не нужно вы юзаете?[/quote]
Сам я им пе пользуюсь, только раньше иногда корректировал скрипт, написанный другим человеком,
но у него удобный синтаксис, он похож на C.

Пётр.
23.11.2014 10:28 #402108

"Peter" написал:
но у него удобный синтаксис, он похож на C.
ага. Именно что "похож". А на самом деле, этот ваш тикель ближе к php, только уродский. Я на нём как-то писал что-то.
24.11.2014 01:55 #402234
"dyasny" написал:
и не вдаваться в пайтонизмы

Можно пример?

24.11.2014 04:19 #402242
"Vitri" написал:
Можно пример?
text
l = [1, 2, 3, 4, 5]
print(sorted(l, key=lambda x: -x))
24.11.2014 04:47 #402245

"dyasny" написал:
l = [1, 2, 3, 4, 5] print(sorted(l, key=lambda x: -x))
это не пайтонизм, а борщеедство из LISP'а. Известно с 60х годов прошлого века, но борщееды(уже третье поколение ЧСХ) до сих пор на это фапают. Если честно, я тут не вижу ни чего хорошего и полезного. IRL это всё не нужно, и работает лишь вот на таких тестовых примерах.

Алсо, в C++11 это тоже работает.
24.11.2014 04:53 #402246
"drBatty" написал:
это не  пайтонизм,  а  борщеедство  из LISP'а. Известно  с 60х годов прошлого века, но борщееды(уже третье поколение ЧСХ) до  сих пор на  это фапают. Если честно, я  тут не вижу ни чего  хорошего и  полезного.  IRL  это  всё не  нужно, и работает  лишь вот на  таких тестовых  примерах.
Алсо, в C++11 это тоже работает.

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

24.11.2014 05:12 #402247

JFF добавил сортировку простыми вставками

text
#!/usr/bin/tcc -run

#include <stdio.h> #include <libgen.h> #include <stdlib.h> #include <string.h> #include <errno.h>

void sort(const int* a[], int n) { int j, k; const int* i; for(j=1; j<n-1; j++) { for(k=j+1, i=a[j+1]; k>0; k--) { if(*i>=*(a[k-1])) break; a[k] = a[k-1]; } a[k] = i; } }

int main(int argc, char* argv[]) { const char* myname = basename(argv[0]); if(argc!=2) { fprintf(stderr, "Usage: %s FILENAME\n", myname); return 1; } int freq[256]; int j; for(j=0; j<256; j++) freq[j] = 0;

FILE* fs = fopen(argv[1], "r"); if(!fs) { fprintf(stderr, "%s:Can't open file '%s' (%s)\n", myname, argv[1], strerror(errno)); return 1; }

int c; while((c = fgetc(fs))!=EOF) freq[c]++; fclose(fs);

const int* a[256]; for(j=0; j<256; j++) a[j] = &freq[j]; sort(a, 256);

double sum = 0.0; for(j=0; j<256; j++) sum += *(a[j]); if(sum==0.0) { fprintf(stderr, "%s:File '%s' is empty\n", myname, argv[1]); return 1; }

for(j=0; j<256; j++) if(*(a[j])>0) { int k = a[j]-freq; printf("%d\t%c\t%d\t%f%%\n", k, k<=32 || k>=128? ' ': k, *(a[j]), (*(a[j])/sum)*100); } return 0; }

Войдите или зарегистрируйтесь, чтобы ответить.