ईओएफ क्या है और इसे कैसे ट्रिगर किया जाए? [बन्द है]


12

यह मेरा सी सोर्स कोड है।

जब मैं इसे उबंटू में बनाता हूं, तो इसे वर्ण मिलना शुरू हो जाता है, लेकिन मुझे नहीं पता कि कार्यक्रम को कैसे समाप्त किया जाए, क्योंकि यह इनपुट ENTERया कैरिज रिटर्न द्वारा समाप्त नहीं होता है ।

EOF का क्या अर्थ है? मैं इसे कैसे ट्रिगर कर सकता हूं?

यह स्रोत डेनिस रिची की एक पुस्तक पर भी है:

#include <stdio.h>
    /* count digits, white space, others */
main ()
{
  int c, i, nwhite, nother;
  int ndigit[10];
  nwhite = nother = 0;
  for (i = 0; i < 10; ++i)
    ndigit[i] = 0;
  while ((c = getchar ()) != EOF)
    if (c >= '0' && c <= '9')
      ++ndigit[c - '0'];
    else if (c == ' ' || c == '\n' || c == '\t')
      ++nwhite;
    else
      ++nother;
  printf ("digits =");
  for (i = 0; i < 10; ++i)
    printf (" %d", ndigit[i]);
  printf (", white space = %d, other = %d\n", nwhite, nother);
}

4
C भाषा -1में EOF के बराबर है। इसे /usr/include/stdio.hस्थूल स्थिरांक के रूप में परिभाषित किया गया है
एडवर्ड टॉर्वाल्ड्स


@edwardtorvalds में प्रवेश -1के रूप में इनपुट काम नहीं करता है :)
सर्गी Kolodyazhnyy

मुझे लगता है कि वही डेनिस रिची किताब यह बताती है।
andy256

इसके अलावा प्रासंगिक: unix.stackexchange.com/questions/110240/… (इस प्रश्न के उत्तर में से कोई भी पूरी तरह से सही नहीं है।)
fkraiem

जवाबों:


23

Tl, डॉ

आप अंतिम इनपुट फ्लश के ठीक बाद CTRL+ Dकीस्ट्रोके के साथ टर्मिनल में चल रहे प्रोग्राम में "ईओएफ को ट्रिगर" कर सकते हैं ।


EOF का क्या अर्थ है? मैं इसे कैसे ट्रिगर कर सकता हूं?

EOF का अर्थ है एंड-टू-फाइल।

इस मामले में "ट्रिगर ईओएफ" का अर्थ मोटे तौर पर "कार्यक्रम को जागरूक करना है कि कोई और इनपुट नहीं भेजा जाएगा"।

इस स्थिति में, चूंकि getchar()कोई वर्ण नहीं पढ़ा जाता है, तो एक ऋणात्मक संख्या वापस आ जाएगी, निष्पादन समाप्त हो जाता है।

लेकिन यह केवल आपके विशिष्ट कार्यक्रम पर लागू नहीं होता है, यह कई अलग-अलग उपकरणों पर लागू होता है।

सामान्य रूप से "ट्रिगर EOF" को अंतिम इनपुट फ्लश (यानी खाली इनपुट भेजकर) के ठीक बाद एक CTRL+ Dकीस्ट्रोक के साथ किया जा सकता है ।

उदाहरण के लिए cat:

% cat >file # Hit ENTER
foo # Hit ENTER and CTRL+D
% 

हुड के नीचे क्या हो रहा है जब मार रहा है CTRL+ Dयह है कि इनपुट अंतिम इनपुट फ्लश के बाद से टाइप किया गया है; जब यह एक खाली इनपुट हो read()जाता है, तो प्रोग्राम के STDIN रिटर्न पर बुलाया syscall 0, getchar()एक नकारात्मक संख्या ( -1GNU C लाइब्रेरी में) लौटाता है और यह बदले में EOF 1 के रूप में व्याख्या किया जाता है ।


1 - /programming//a/1516177/4316166


2
संकलन कार्य करता है, क्योंकि अल्पविराम एक ही पंक्ति में होने से बाध्य नहीं है। इसके अलावा, EOF पर महान व्याख्या :)
पॉलियस'ukys

@ PauliusŠukys हुह, आप सही कह रहे हैं। मेरा C थोड़ा कठोर है। :)
कोस

1
iirc EOF को मानक के अनुसार -1 नहीं परिभाषित किया गया है। यह सिर्फ उदाहरण के लिए glibc में क्या होता है।
larkey


1
EOF '' खाली इनपुट '' भेजने में शामिल नहीं है, और आप जो उत्तर देते हैं, वह अन्यथा नहीं कहता है। यह बैंड सिग्नल से बाहर है। टर्मिनल के मामले में इसे Ctrl / d लिखकर भेजा जाता है।
user207421

4

टीएल; डीआर : ईओएफ एक चरित्र नहीं है, यह एक मैक्रो है जिसका उपयोग इनपुट-रीडिंग फ़ंक्शन के नकारात्मक रिटर्न के मूल्यांकन के लिए किया जाता है। एक का उपयोग कर सकते हैं Ctrl+ चरित्र Dभेजने के लिए EOTजो फ़ंक्शन रिटर्न को मजबूर करेगा-1

हर प्रोग्रामर को RTFM होना चाहिए

आइए हम "CA संदर्भ मैनुअल" देखें, जो कि हार्बिसन और स्टील, 4 थ एड द्वारा किया गया है। 1995 से, पृष्ठ 317:

नकारात्मक पूर्णांक EOF एक मान है जो "वास्तविक चरित्र" का एन्कोडिंग नहीं है। । । उदाहरण के लिए fget (खंड 15.6) जब फ़ाइल के अंत में EOF देता है , क्योंकि पढ़ने के लिए कोई "वास्तविक चरित्र" नहीं है।

अनिवार्य रूप EOFसे एक चरित्र नहीं है, बल्कि प्रतिनिधित्व करने के लिए कार्यान्वित एक पूर्णांक मूल्य है । इस प्रकार, कोस का उत्तर जहां तक ​​जाता है, सही है, लेकिन यह "खाली" इनपुट प्राप्त करने के बारे में नहीं है। महत्वपूर्ण नोट यह है कि यहां ईओएफ एक वास्तविक चरित्र को इंगित करने के लिए नहीं, तुलनात्मक मूल्य के रिटर्न ( ) के रूप में कार्य करता है । का समर्थन करता है कि:stdio.h-1getchar()man getchar

प्रतिलाभ की मात्रा

fgetc (), getc () और getchar () फ़ाइल या त्रुटि के अंत में एक int या EOF को अहस्ताक्षरित चार कलाकारों के रूप में पढ़ा गया वर्ण लौटाते हैं।

हो जाता है () और फ़्यूज़ () सफलता पर वापस, और त्रुटि पर या जब फ़ाइल का अंत तब होता है जब कोई वर्ण पढ़ा नहीं गया होता है।

ungetc () सफलता पर ग, या त्रुटि पर EOF।

whileपाश पर विचार करें - इसका प्राथमिक उद्देश्य कार्रवाई को दोहराना है यदि कोष्ठक में स्थिति सत्य है । दुबारा देखो:

while ((c = getchar ()) != EOF)

यह मूल रूप से कहता है कि यदि c = getchar()सफल कोड ( 0या ऊपर) लौटाता है तो सामान रखना है; वैसे यह एक सामान्य बात है, सफल कमांड चलाने की कोशिश करें, echo $?फिर विफल हो जाते हैं echo $?और वे संख्या देखते हैं जो वे वापस लौटते हैं)। इसलिए यदि हम सफलतापूर्वक चरित्र प्राप्त करते हैं और सी को सहायता देते हैं, तो लौटा हुआ स्थिति कोड 0 है, विफल -1 है। EOFके रूप में परिभाषित किया गया है -1। इसलिए जब स्थिति -1 == -1होती है, तो लूप बंद हो जाता है। और ऐसा कब होगा? जब पाने के लिए कोई और चरित्र नहीं होता, जब c = getchar()असफल होता है। आप लिख सकते हैं while ((c = getchar ()) != -1)और यह अभी भी काम करेगा

इसके अलावा, हम वास्तविक कोड पर वापस जाते हैं, यहाँ एक अंश है stdio.h

/* End of file character.
   Some things throughout the library rely on this being -1.  */
#ifndef EOF
# define EOF (-1)
#endif

ASCII कोड और EOT

यद्यपि ईओएफ चरित्र एक वास्तविक चरित्र नहीं है, हालांकि, एक EOT(ट्रांसमिशन का अंत) चरित्र मौजूद है, जिसमें एएससीआईआई 04 का दशमलव मान है; यह Ctrl+ Dशॉर्टकट (मेटा वर्ण के रूप में भी दर्शाया गया है) से जुड़ा हुआ है ^D। ट्रांसमिशन चॅकर का अंत तब होता था जब टेलीफोन कनेक्शन को नियंत्रित करने के लिए कंप्यूटर का उपयोग किया जाता था, इसलिए डेटा रास्ते की एक धारा को बंद करने का संकेत देता था, इसलिए "ट्रांसमिशन का अंत" नामकरण।

तो यह है कि इस तरह के कार्यक्रम के लिए ascii मूल्य भेजने के लिए संभव है, ध्यान दें $'\04'जो EOT है:

skolodya@ubuntu:$ ./a.out  <<< "a,b,c $'\04'"                                  
digits = 1 0 0 0 1 0 0 0 0 0, white space = 2, other = 9

इस प्रकार, हम कह सकते हैं कि यह मौजूद है, लेकिन यह प्रिंट करने योग्य नहीं है

पक्षीय लेख

हम अक्सर भूल जाते हैं कि पिछले कंप्यूटरों में बहुमुखी नहीं थे - डिजाइनरों को हर कीबोर्ड कुंजी का उपयोग करना पड़ता है। इस प्रकार, EOTCtrlD के साथ चरित्र भेजना अभी भी "एक चरित्र भेजना" है, टाइपिंग कैपिटल A, ShiftA के विपरीत नहीं, आप अभी भी कंप्यूटर को उपलब्ध कुंजियों के साथ एक इनपुट देते हैं। इस प्रकार ईओटी एक वास्तविक चरित्र है जो उपयोगकर्ता से आता है, यह कंप्यूटर द्वारा पठनीय है (हालांकि प्रिंट करने योग्य नहीं है, मानव द्वारा दिखाई नहीं देता है), यह कंप्यूटर मेमोरी में मौजूद है

बाइट कमांडर की टिप्पणी

यदि आप / dev / null से पढ़ने की कोशिश करते हैं, तो एक EOF को भी वापस करना चाहिए, है ना? या मुझे वहाँ क्या मिलता है?

हां, बिल्कुल सही, क्योंकि /dev/nullपढ़ने के लिए कोई वास्तविक चरित्र नहीं है, इसलिए यह कोड c = getchar()लौटाएगा -1, और प्रोग्राम तुरंत छोड़ देगा। फिर से कमांड EOF को वापस नहीं करता है। EOF -1 के बराबर स्थिर चर है, जिसका उपयोग हम गेटचार फ़ंक्शन के रिटर्न कोड की तुलना करने के लिए करते हैंEOFचरित्र के रूप में मौजूद नहीं है, यह सिर्फ एक स्थिर मूल्य है stdio.h

डेमो:

# cat /dev/null shows there's no readable chars
DIR:/xieerqi
skolodya@ubuntu:$ cat /dev/null | cat -A        

# Bellow is simple program that will open /dev/null for reading. Note the use of literal -1                                   
   DIR:/xieerqi
skolodya@ubuntu:$ cat readNull.c                                               
#include<stdio.h>

void main()
{
   char c;
    FILE *file;
    file = fopen("/dev/null", "r");

    if (file) 
    {
    printf ("Before while loop\n");
        while ((c = getc(file)) != -1)
            putchar(c);
    printf("After while loop\n"); 
    fclose(file);
    }
}

DIR:/xieerqi
skolodya@ubuntu:$ gcc readNull.c -o readNull                                   

DIR:/xieerqi
skolodya@ubuntu:$ ./readNull
Before while loop
After while loop

ताबूत में एक और कील

कभी-कभी यह साबित करने का प्रयास किया जाता है कि EOF इस तरह के कोड वाला एक चरित्र है:

#include <stdio.h>
int main(void)
{
    printf("%c", EOF);
    return 0;
}

इसके साथ समस्या यह है कि चार डेटेटाइप एक हस्ताक्षरित या अहस्ताक्षरित मूल्य हो सकता है। इसके अलावा वे सबसे छोटे पते योग्य डेटाटाइप हैं जो उन्हें माइक्रोकंट्रोलर में बहुत उपयोगी बनाते हैं, जहां मेमोरी सीमित है। इसलिए घोषित करने के बजाय int foo = 25;छोटी स्मृति char foo = 25;या कुछ इसी तरह के माइक्रोकंट्रोलर में देखना आम है । इसके अलावा, चार्ट पर हस्ताक्षर किए या अहस्ताक्षरित हो सकते हैं

कोई यह सत्यापित कर सकता है कि बाइट्स में आकार इस तरह के प्रोग्राम के साथ है:

#include <stdio.h>
int main(void)
{
    printf("Size of int: %lu\n",sizeof(int));
    printf("Sieze of char: %lu\n",sizeof(char));
    //printf("%s", EOF);
    return 0;
}

skolodya@ubuntu:$ ./EOF                                                        
Size of int: 4
Sieze of char: 1

वास्तव में क्या बात है? मुद्दा यह है कि ईओएफ को -1 के रूप में परिभाषित किया गया है, लेकिन चार डेटाटाइप पूर्णांक मानों को प्रिंट कर सकता है

ठीक । । .तो क्या होगा अगर हम चार को स्ट्रिंग के रूप में प्रिंट करने की कोशिश करते हैं?

#include <stdio.h>
int main(void)
{
    printf("%s", EOF);
    return 0;
}

स्पष्ट रूप से एक त्रुटि, लेकिन फिर भी, त्रुटि हमें कुछ दिलचस्प बताएगी:

skolodya @ ubuntu: $ gcc EOF.c -o EOF
EOF.c: फ़ंक्शन 'मुख्य' में: EOF.c: 4: 5: चेतावनी: प्रारूप '% s' प्रकार 'char *' के तर्क की अपेक्षा करता है, लेकिन तर्क 2 टाइप 'int' [-रूपत =] प्रिंटफ ("% s", EOF);

हेक्स मान

EOF को एक हेक्स मान के रूप में प्रिंट करना FFFFFFFF, एक 16 बिट (8 बाइट) मान, दो की प्रशंसा करता है -1

#include <stdio.h>
int main(void)
{
    printf("This is EOF: %X\n", EOF);
    printf("This is Z: %X\n",'Z');
    return 0;
}

आउटपुट:

DIR:/xieerqi
skolodya@ubuntu:$ ./EOF                                                        
This is EOF: FFFFFFFF
This is Z: 5A

निम्नलिखित कोड के साथ एक और उत्सुक बात होती है:

#include <stdio.h>
int main(void)
{
   char c;
   if (c = getchar())
    printf ("%x",c);
    return 0;
}

अगर एक Shift+ दबाता है A, तो हमें हेक्स मान 41 मिलता है, जाहिर है कि एएससीआईआई तालिका में भी। लेकिन Ctrl+ के लिए D, हमारे पास ffffffff, फिर से - में getchar()संग्रहीत मूल्य का रिटर्न मूल्य है c

DIR:/xieerqi
skolodya@ubuntu:$ gcc  EOF.c -o ASDF.asdf                                      

DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf                                                  
A
41
DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf                                                  
ffffffff

अन्य भाषाओं का संदर्भ लें

ध्यान दें कि अन्य भाषा इस भ्रम से बचती हैं, क्योंकि वे एक फ़ंक्शन निकास स्थिति का मूल्यांकन करने पर काम करते हैं, इसकी तुलना मैक्रो के साथ नहीं करते हैं। जावा में फ़ाइल कैसे पढ़ता है?

    File inputFile  = new File (filename);
    Scanner readFile = new Scanner(inputFile);
    while (readFile.hasNext())
        { //more code bellow  }

अजगर के बारे में कैसे?

with open("/etc/passwd") as file:
     for line in file:
          print line

महान बिंदु, वास्तव में किसी न किसी बिंदु पर एक चरित्र भेजा जाता है।
कोस

मुझे लगता है कि ईओएफ चरित्र कुछ ऐसा है जो अनुवाद में खो गया है, क्योंकि यह वास्तविक चरित्र नहीं है, लेकिन ईओटी एक वास्तविक, वास्तविक चरित्र है। जाओ पता लगाओ !
सर्गी कोलोडियाज़नी

1
यदि आप पढ़ने की कोशिश करते हैं /dev/null, तो आपको ईओएफ को वापस करना चाहिए, है ना? या मुझे वहाँ क्या मिलता है?
बाइट कमांडर

@ByteCommander पता लगाने देता है। बिल्ली / देव / नल | बिल्ली।
सेर्गेई कोलोडियाज़नी

@ByteCommander ने आपकी टिप्पणी को संबोधित करते हुए धारा जोड़ी
Sergiy Kolodyazhnyy

2

EOF फ़ाइल के अंत के लिए खड़ा है । हालांकि मुझे नहीं पता कि निम्नलिखित प्रतीक को कैसे ट्रिगर किया जाए, आप एक फ़ाइल को पाइपिंग के माध्यम से निम्न प्रोग्राम चला सकते हैं, जो अंत में ईओएफ सिग्नल भेजता है :

echo "Some sample text" | ./a.out

a.outआपका संकलित स्रोत कहां है


1
इसे पहले ही अपवोट कर दिया गया है, हालाँकि एक साइड नोट पर EOF एक कैरेक्टर नहीं है, मुझे लगता है कि गलत धारणा इस तथ्य से उत्पन्न होती है जिसे CTRL केस्ट्रोक के माध्यम से संकेतित किया जाता है, जो आमतौर पर गैर-प्रिंट करने योग्य वर्णों को इनपुट करने का तरीका है। जैसा कि मैं समझता हूं कि वास्तव में ऐसा होता है कि सभी इनपुट फ्लश हो जाते हैं और इनपुट को फ्लश किया जा रहा है खाली read()(syscall) वापस आ जाएगा 0, जिसे ईओएफ के रूप में व्याख्या किया गया है: stackoverflow.com/a/1516177/4316166
'24

@kos, आप सही कह रहे हैं, यह एक सिग्नल के बाद है।
पॉलियस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.