2012-04-03 12 views
9

चूंकि यूनिक्स में उन सभी अद्भुत फ़िल्टर-जैसे प्रोग्राम हैं (जैसे grep, sed, tr और बहुत आगे), मानक सी में से किसी एक को लिखने का सबसे आसान तरीका क्या है?मैं सी में एक फ़िल्टर प्रोग्राम कैसे लिखूं?

फिल्टर द्वारा, मेरा मतलब है एक मानक जो मानक इनपुट पढ़ता है, डेटा के कुछ हेरफेर करता है, और फिर इसे मानक आउटपुट में लिखता है।

grep xyzzy input.file | tr '[A-Z]' '[a-z]' | sed 's/plugh/PLUGH/g' 

(| पाइप प्रतीकों में से प्रत्येक के मानक इनपुट के लिए पिछला आदेश के मानक आउटपुट जोड़ता है: यह, आदेशों की पाइपलाइनों के निर्माण प्रत्येक तरह के रूप में डेटा, के कुछ अतिरिक्त हेरफेर प्रदर्शन के साथ करने में उपयोगी है अगला, इसलिए पाइपलाइन रूपक)।

मान लें कि मुझे एक ऐसे व्यक्ति की आवश्यकता है जो सभी अपरकेस अक्षरों को लोअरकेस में परिवर्तित कर दे। और, हाँ, मुझे पता है यह विशेष समस्या यूनिक्स के साथ हल किया जा सकता है:

tr '[A-Z]' '[a-z]' 

लेकिन यह है कि सिर्फ एक उदाहरण है।

मैं वास्तव में क्या हूं इस तरह के फ़िल्टर करने के लिए सबसे सरल मानक सी स्रोत कोड है।

+2

मुझे याद आ रही: उदाहरण के लिए, आपके द्वारा लोअरकेस के रूप में एक पूरी फ़ाइल (यदि आप Windows मशीनों पर type उपयोग कर सकते हैं) प्राप्त कर सकते हैं? 1 अप्रैल दो दिन पहले था ... –

+1

आपके द्वारा उल्लिखित सभी टूल्स के लिए, आप आसानी से स्रोत कोड पा सकते हैं। उन्हें यह देखने के लिए क्यों नज़र डालें कि उन्हें कैसे कार्यान्वित किया जाता है? –

+2

@ माइकल, नहीं, यह तब आया जब मैं एक और सवाल का जवाब दे रहा था, और मुझे एहसास हुआ कि इसमें कोई सवाल नहीं था। दिशानिर्देशों के अनुसार (एसओ उपयोगकर्ताओं के सभी स्तरों के लिए और अपने प्रश्नों का उत्तर देने के लिए), मैंने सोचा कि मैं इसे रखूंगा। जाहिर है, _I_ यह जानना है कि यह कैसे करना है, लेकिन मैं किसी और को जवाब देने की बजाय प्रतिलिपि नहीं दूंगा (जब तक वे उस दिन के एक जोड़े में नहीं होते हैं, तो मैं अधिकतम :-) – paxdiablo

उत्तर

6

आप getline इस्तेमाल कर सकते हैं के रूप में @hroptatyr द्वारा वर्णित है, लेकिन आप एक बहुत सरल कुछ कर सकते हैं:

#include <stdio.h> 
#include <ctype.h> 
int main(void) { 
    int c; 
    while ((c = getchar()) != EOF) 
     putchar(tolower(c)); 
    return 0; 
} 
+3

कैसे प्राप्त करें मुझे लगता है कि किसी को वास्तव में मुख्य बिंदु समझा जाना चाहिए: एक फ़िल्टर एक प्रोग्राम है जो' stdin' पढ़ता है कुछ करता है (जो डेटा में 'बिल्ली' जैसी कुछ भी नहीं कर सकता है और परिवर्तित डेटा को 'stdout' में लिखता है। बेशक, कई फ़िल्टर उस से बहुत अधिक करते हैं, जैसे विकल्पों द्वारा निर्देशित 'stdin'/'stdout' के अलावा अन्य फ़ाइलों को पढ़ने/लिखना। लेकिन मुझे लगता है कि एक फिल्टर की मूल अवधारणा है। –

3

छद्म कोड में:

do 
    line = read(stdin); 
    filter(line); 
    print(line); 
until no_more_lines 

वास्तविक कोड में:

char *line = NULL; 
size_t len = 0U; 
ssize_t n; 

while ((n = getline(&line, &len, stdin)) >= 0) { 
     /* LINE is of length N, filter it */ 
     filter(line, n); 
     /* print it */ 
     fputs(line, stdout); 
} 
free(line); 

और filter() लगता है:

static void filter(char *line, size_t length) 
{ 
     while ((*line++ = tolower(*line))); 
} 

संपादित करें: परिभाषित करने के लिए मत भूलना _POSIX_C_SOURCE >= 200809L या _XOPEN_SOURCE >= 700 । और के लिए getline() और ctype.h के लिए stdio.h शामिल करना न भूलें।

+0

'getline'? Whassat? :-) – paxdiablo

+0

@paxdiablo एक फ़ंक्शन शायद कहीं और परिभाषित किया गया है। – glglgl

+0

@paxdiablo do 'man 3 getline' और प्रबुद्ध हो। –

3

एक "फिल्टर" कार्यक्रम बस एक प्रोग्राम है जो मानक इनपुट स्ट्रीम (stdin) से पढ़ता है और मानक आउटपुट स्ट्रीम (stdout) को लिखता है। पढ़ने के डेटा लिखने से पहले, डेटा को आम तौर पर किसी तरह से परिवर्तित किया जाता है (यदि आप किसी भी रूपांतरण या फ़िल्टरिंग को पूर्ववत नहीं करते हैं, तो आपने मूल रूप से cat प्रोग्राम लिखा था जो कि जो कुछ भी दिया गया है उसे प्रिंट करता है)। फ़िल्टर प्रोग्राम की शक्ति इस तथ्य से आती है कि वे यह नहीं बताते कि उनका इनपुट कहां से आता है या आउटपुट कहां जा रहा है। इसके बजाए, इनपुट/आउटपुट चैनल प्रदान करने के लिए कार्यक्रम के कॉलर पर निर्भर है।

#include <stdio.h> 

int filter(FILE *input, FILE *output); 

int main(void) 
{ 
    const int retval = filter(stdin, stdout); 
    fflush(stdout); 
    return retval; 
} 

यह है कि:

एक फिल्टर कार्यक्रम कुछ इस तरह नज़र आ सकते कोर (आप अपने खुद के फिल्टर कार्यक्रमों के लिए एक टेम्पलेट के रूप में उपयोग कर सकते हैं)। वास्तविक कार्य filter फ़ंक्शन द्वारा किया जाता है जो आपके इच्छित परिवर्तन को निष्पादित करता है।उदाहरण के लिए, यहाँ एक साधारण प्रोग्राम है जो इनपुट फ़ाइल से पात्रों पढ़ता है, लोअरकेस उन्हें बदल जाता है, और फिर उन्हें आउटपुट फ़ाइल के लिए प्रिंट है:

#include <stdio.h> 
#include <ctype.h> /* for tolower */ 

int filter(FILE *input, FILE *output) 
{ 
    while (!feof(input)) { 
     if (ferror(input)) { 
      return 1; 
     } 
     fputc(tolower(fgetc(input)), output); 
    } 
    return 0; 
} 

int main(void) 
{ 
    const int retval = filter(stdin, stdout); 
    fflush(stdout); 
    return retval; 
} 

आप संकलन और इस कार्यक्रम चलाते हैं, तो यह बस बैठ जाएगा वहाँ और धैर्यपूर्वक मानक इनपुट फ़ाइल stdin से डेटा पढ़ने के लिए प्रतीक्षा करें। यह फ़ाइल आमतौर पर कंसोल से जुड़ी होती है, जिसका अर्थ है कि आपको हाथ से कुछ डेटा दर्ज करना होगा। हालांकि, कमांड शैल पाइप नामक एक फीचर को कार्यान्वित करते हैं जो आपको एक कमांड के आउटपुट को दूसरे इनपुट में पाइप करने की अनुमति देता है। यह शक्तिशाली कमांड बनाने के लिए pipeline में एकाधिक प्रोग्रामों को लिखने की अनुमति देता है।

$ echo Hello | lower 
hello 
$ 

चूंकि हमारे फिल्टर कार्यक्रम जहां डाटा पढ़ने के लिए से आ रही है परिभाषित नहीं करता है, हम गठबंधन कर सकते हैं:

यहाँ कैसे हम अपने फिल्टर कार्यक्रम (यह मानते हुए आप बुलाया परिणामस्वरूप द्विआधारी lower) इस्तेमाल कर सकते हैं है यह stdout पर आउटपुट उत्पादन के सभी प्रकार के कार्यक्रमों के साथ।

कुछ
$ cat myfile.txt 
Hello, World! 
This is a simple test. 

$ cat myfile.txt | lower 
hello, world! 
this is a simple test. 

$ 
+0

'fflush (stdout);' बेकार लगता है: "यदि' main' फ़ंक्शन अपने मूल कॉलर पर वापस आ जाता है, [...] सभी खुली फ़ाइलें बंद होती हैं (इसलिए सभी आउटपुट स्ट्रीम फ़्लश हो जाती हैं) प्रोग्राम समाप्ति से पहले । " (आईएसओ/आईईसी 98 99: 1 999, 7.9.13, §5)। –

+0

@undur_gongor: होनस्ट होने के लिए, मैं सहमत हूं; मेरे पहले संस्करण में मेरे पास 'fflush' कॉल नहीं था।हालांकि, एक विंडोज एक्सपी बॉक्स पर प्रोग्राम की कोशिश करते समय, मैंने देखा कि मुझे कोई आउटपुट नहीं मिला। स्पष्ट रूप से 'stdout' flushing में मदद की - मैंने आगे की जांच को परेशान नहीं किया (मेरे पास विंडोज़ पर सी एपीआई के साथ कम से कम तारकीय अनुभव हैं)। –

-4
L1: 
mov dx,081 
mov cx,1 
mov bx,0 
mov ax,03f00 
int 021 
cmp ax,0 
je L2 
cmp b[081],'a' 
jb L3 
cmp b[081],'z' 
ja L3 
sub b[081],020 
L3: 
mov dx,081 
mov cx,1 
mov bx,1 
mov ax,04000 
int 021 
jmp L1 
L2: 
mov ax,04c00 
int 021 

; Example in A86 Assembler see eji.com for A86/D86 
+1

क्या आप इसे और समझा सकते हैं? –

संबंधित मुद्दे