खोज…


वाक्य - विन्यास

  • #include <stdio.h> / * निम्न अनुभागों में से किसी का उपयोग करने के लिए इसे शामिल करें * *
  • File * fopen (const char * path, const char * mode); / * निर्दिष्ट मोड के साथ पथ पर फ़ाइल पर एक धारा खोलें * /
  • File * freopen (const char * path, const char * mode, FILE * stream); / * निर्दिष्ट मोड के साथ पथ पर फ़ाइल पर एक मौजूदा स्ट्रीम फिर से खोलें * /
  • int fclose (FILE * स्ट्रीम); / * एक खोला स्ट्रीम बंद करें * /
  • size_t fread (void * ptr, size_t size, size_t nmemb, FILE * स्ट्रीम); / * आकार के सबसे nmemb तत्वों को स्ट्रीम से प्रत्येक बाइट्स पर पढ़ें और उन्हें ptr में लिखें। पढ़े गए तत्वों की संख्या लौटाता है। * /
  • size_t fwrite (const void * ptr, size_t size, size_t nmemb, FILE * स्ट्रीम); / * आकार की लिखें nmemb तत्वों धारा को ptr से प्रत्येक बाइट्स। लिखित तत्वों की संख्या लौटाता है। * /
  • int fseek (FILE * स्ट्रीम, लॉन्ग ऑफ़सेट, इंट व्हेंस); / * स्ट्रीम के कर्सर को ऑफसेट पर सेट करें, जिसे व्हाट्सएप द्वारा बताया गया है, और यदि यह सफल रहा तो 0 रिटर्न देता है। * /
  • लम्बी फ़ेल (फ़ील * स्ट्रीम); / * धारा की शुरुआत से वर्तमान कर्सर स्थिति की भरपाई करें। * /
  • शून्य रिवाइंड (FILE * स्ट्रीम); / * फ़ाइल की शुरुआत में कर्सर की स्थिति सेट करें। * /
  • int fprintf (File * fout, const char * fmt, ...); / * Fout पर प्रिंटफ़ प्रारूप स्ट्रिंग लिखता है * /
  • फील * स्टड; / * मानक इनपुट स्ट्रीम * /
  • फ़ाइल * stdout; / * मानक उत्पादन धारा * /
  • फ़ाइल * stderr; / * मानक त्रुटि स्ट्रीम * /

पैरामीटर

पैरामीटर विवरण
const char * मोड फ़ाइल-समर्थित स्ट्रीम के उद्घाटन मोड का वर्णन करने वाला एक स्ट्रिंग। संभावित मूल्यों के लिए टिप्पणी देखें।
int whence हो सकता है SEEK_SET सेट करने के लिए फ़ाइल की शुरुआत से, SEEK_END अपने अंत से सेट करने के लिए, या SEEK_CUR वर्तमान कर्सर मूल्य के लिए सेट रिश्तेदार को। नोट: SEEK_END गैर-पोर्टेबल है।

टिप्पणियों

मोड तार:

freopen() में मोड स्ट्रिंग्स fopen() और freopen() उन मूल्यों में से एक हो सकते हैं:

  • "r" : फ़ाइल को केवल-पढ़ने के लिए मोड में खोलें, फ़ाइल की शुरुआत में सेट किए गए कर्सर के साथ।
  • "r+" : फ़ाइल को रीड-राइट मोड में खोलें, कर्सर को फ़ाइल की शुरुआत में सेट करें।
  • "w" : फ़ाइल को केवल-लिखित मोड में खोलें या बनाएँ, जिसकी सामग्री 0 बाइट्स से कम हो। कर्सर फ़ाइल की शुरुआत में सेट किया गया है।
  • "w+" : फ़ाइल को रीड-राइट मोड में खोलें या बनाएं, जिसकी सामग्री 0 बाइट्स से कम हो। कर्सर फ़ाइल की शुरुआत में सेट किया गया है।
  • "a" : फ़ाइल को केवल-लेखन मोड में खोलें या बनाएँ, जिसमें कर्सर फ़ाइल के अंत में सेट हो।
  • "a+" : फ़ाइल को रीड-राइट मोड में खोलें या बनाएँ, जिसमें फ़ाइल की शुरुआत में रीड-कर्सर सेट है। हालाँकि, आउटपुट हमेशा फ़ाइल के अंत में जोड़ा जाएगा।

इनमें से प्रत्येक फ़ाइल मोड में प्रारंभिक अक्षर (जैसे "rb" या "a+b" या "ab+" ) के बाद एक b जोड़ा जा सकता है। b मतलब है कि उन प्रणालियों पर पाठ फ़ाइल के बजाय फ़ाइल को द्विआधारी फ़ाइल के रूप में माना जाना चाहिए जहां अंतर है। यह यूनिक्स जैसी प्रणालियों पर फर्क नहीं करता है; यह विंडोज सिस्टम पर महत्वपूर्ण है। (इसके अतिरिक्त, विंडोज़ fopen 'टेक्स्ट फ़ाइल' - और कई अन्य प्लेटफ़ॉर्म-विशिष्ट विकल्पों को इंगित करने के लिए b बजाय एक स्पष्ट t अनुमति देता है।)

C11
  • "wx" : केवल-लिखित मोड में एक पाठ फ़ाइल बनाएँ। फ़ाइल मौजूद नहीं हो सकती है
  • "wbx" : केवल- "wbx" मोड में एक बाइनरी फ़ाइल बनाएँ। फ़ाइल मौजूद नहीं हो सकती है

x , यदि मौजूद है, तो मोड स्ट्रिंग में अंतिम वर्ण होना चाहिए।

फ़ाइल को खोलें और लिखें

#include <stdio.h>   /* for perror(), fopen(), fputs() and fclose() */
#include <stdlib.h>  /* for the EXIT_* macros */
 
int main(int argc, char **argv)
{
    int e = EXIT_SUCCESS;

    /* Get path from argument to main else default to output.txt */
    char *path = (argc > 1) ? argv[1] : "output.txt";

    /* Open file for writing and obtain file pointer */
    FILE *file = fopen(path, "w");
    
    /* Print error message and exit if fopen() failed */
    if (!file) 
    {
        perror(path);
        return EXIT_FAILURE;
    }

    /* Writes text to file. Unlike puts(), fputs() does not add a new-line. */
    if (fputs("Output in file.\n", file) == EOF)
    {
        perror(path);
        e = EXIT_FAILURE;
    }

    /* Close file */
    if (fclose(file)) 
    {
        perror(path);
        return EXIT_FAILURE;
    }
    return e;
}

यह प्रोग्राम मुख्य को तर्क में दिए गए नाम से फाइल खोलता है, यदि कोई तर्क नहीं दिया जाता है, तो output.txt को डिफ़ॉल्ट करना। यदि समान नाम वाली फ़ाइल पहले से मौजूद है, तो उसकी सामग्री को छोड़ दिया जाता है और फ़ाइल को एक नई खाली फ़ाइल के रूप में माना जाता है। यदि फाइल्स पहले से मौजूद नहीं हैं तो fopen() कॉल इसे बनाता है।

यदि किसी कारण से fopen() कॉल विफल हो जाता है, तो यह NULL मान लौटाता है और वैश्विक errno चर मान सेट करता है। इसका मतलब है कि कार्यक्रम के बाद दिए गए मान का परीक्षण कर सकते fopen() कॉल और उपयोग perror() करता है, तो fopen() विफल रहता है।

यदि fopen() कॉल सफल होता है, तो यह एक वैध FILE पॉइंटर लौटाता है। इस सूचक को तब तक इस फ़ाइल को संदर्भित करने के लिए इस्तेमाल किया जा सकता है जब तक कि उस पर fclose() कहा जाता है।

fputs() फ़ंक्शन फ़ाइल के किसी भी पिछले सामग्री की जगह, खुली हुई फ़ाइल को दिए गए पाठ को लिखता है। इसी तरह fopen() , fputs() फ़ंक्शन भी errno मान सेट करता है यदि यह विफल रहता है, हालांकि इस मामले में फ़ंक्शन EOF को विफल इंगित करता है (यह अन्यथा एक गैर-नकारात्मक मान लौटाता है)।

fclose() फ़ंक्शन किसी भी बफ़र्स को फ्लश करता है, फ़ाइल को बंद करता है और FILE * द्वारा इंगित मेमोरी को मुक्त करता है। रिटर्न वैल्यू संकेत के रूप में पूरा होने का संकेत fputs() जैसा कि सफल होने पर if 0 ’देता है), फिर असफल होने की स्थिति में फिर से errno मान सेट करना।

fprintf

आप किसी फ़ाइल पर fprintf उपयोग उसी तरह कर सकते हैं जैसे आप printf साथ कंसोल पर कर सकते हैं। उदाहरण के लिए आप खेल जीत, नुकसान और संबंधों पर नज़र रख सकते हैं

/* saves wins, losses and, ties */
void savewlt(FILE *fout, int wins, int losses, int ties)
{
    fprintf(fout, "Wins: %d\nTies: %d\nLosses: %d\n", wins, ties, losses);
}

एक साइड नोट: कुछ सिस्टम (बदनाम, विंडोज) का उपयोग नहीं करते हैं जो अधिकांश प्रोग्रामर "सामान्य" लाइन एंडिंग कहते हैं। जबकि यूनिक्स जैसे सिस्टम लाइनों को समाप्त करने के लिए \ n का उपयोग करते हैं, Windows वर्णों की एक जोड़ी का उपयोग करता है: \ r (गाड़ी वापसी) और \ n (लाइन फीड)। इस अनुक्रम को आमतौर पर CRLF कहा जाता है। हालांकि, सी का उपयोग करते समय, आपको इन अत्यधिक प्लेटफ़ॉर्म-निर्भर विवरणों के बारे में चिंता करने की आवश्यकता नहीं है। एसी कंपाइलर को अंत प्लेटफ़ॉर्म लाइन को समाप्त करने के लिए \ n के हर उदाहरण को बदलने की आवश्यकता होती है। इसलिए एक विंडोज कंपाइलर \ n को \ r \ n में बदल देगा, लेकिन एक UNIX कंपाइलर इसे जैसा रखेगा।

चलाने की प्रक्रिया

#include <stdio.h>

void print_all(FILE *stream)
{
    int c;
    while ((c = getc(stream)) != EOF)
        putchar(c);
}
int main(void)
{
    FILE *stream;

    /* call netstat command. netstat is available for Windows and Linux */
    if ((stream = popen("netstat", "r")) == NULL)
        return 1;
  
    print_all(stream);
    pclose(stream);
    return 0;
}

यह कार्यक्रम popen() ) के माध्यम से एक प्रक्रिया ( netstat ) चलाता है और प्रक्रिया से सभी मानक आउटपुट को पढ़ता है और मानक आउटपुट को गूँजता है।

नोट: popen() मानक C लाइब्रेरी में मौजूद नहीं है, लेकिन यह POSIX C का एक हिस्सा है )

गेटलाइन () का उपयोग करके फ़ाइल से लाइनें प्राप्त करें

POSIX C लाइब्रेरी getline() फ़ंक्शन को परिभाषित करता है। यह फ़ंक्शन लाइन सामग्री को होल्ड करने के लिए एक बफर आवंटित करता है और नई लाइन, लाइन में वर्णों की संख्या और बफर के आकार को लौटाता है।

उदाहरण प्रोग्राम जो प्रत्येक पंक्ति को example.txt :

#include <stdlib.h>
#include <stdio.h>  


#define FILENAME "example.txt"

int main(void)
{
  /* Open the file for reading */
  char *line_buf = NULL;
  size_t line_buf_size = 0;
  int line_count = 0;
  ssize_t line_size;
  FILE *fp = fopen(FILENAME, "r");
  if (!fp)
  {
    fprintf(stderr, "Error opening file '%s'\n", FILENAME);
    return EXIT_FAILURE;
  }

  /* Get the first line of the file. */
  line_size = getline(&line_buf, &line_buf_size, fp);

  /* Loop through until we are done with the file. */
  while (line_size >= 0)
  {
    /* Increment our line count */
    line_count++;

    /* Show the line details */
    printf("line[%06d]: chars=%06zd, buf size=%06zu, contents: %s", line_count,
        line_size, line_buf_size, line_buf);

    /* Get the next line */
    line_size = getline(&line_buf, &line_buf_size, fp);
  }

  /* Free the allocated line buffer */
  free(line_buf);
  line_buf = NULL;

  /* Close the file now that we are done with it */
  fclose(fp);

  return EXIT_SUCCESS;
}

इनपुट फ़ाइल example.txt

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

उत्पादन

line[000001]: chars=000015, buf size=000016, contents: This is a file
line[000002]: chars=000012, buf size=000016, contents:   which has
line[000003]: chars=000015, buf size=000016, contents: multiple lines
line[000004]: chars=000030, buf size=000032, contents:     with various indentation,
line[000005]: chars=000012, buf size=000032, contents: blank lines
line[000006]: chars=000001, buf size=000032, contents: 
line[000007]: chars=000001, buf size=000032, contents: 
line[000008]: chars=000001, buf size=000032, contents: 
line[000009]: chars=000150, buf size=000160, contents: a really long line to show that getline() will reallocate the line buffer if the length of a line is too long to fit in the buffer it has been given,
line[000010]: chars=000042, buf size=000160, contents:  and punctuation at the end of the lines.
line[000011]: chars=000001, buf size=000160, contents: 

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

एक अन्य विकल्प getdelim() । यह getline() के समान है getline() इसके अलावा आप लाइन को समाप्त करने वाले वर्ण को निर्दिष्ट करते हैं। यह केवल तभी आवश्यक है जब आपके फ़ाइल प्रकार के लिए लाइन का अंतिम वर्ण '\ n' न हो। getline() विंडोज टेक्स्ट फ़ाइलों के साथ भी काम करती है क्योंकि मल्टीबाइट लाइन समाप्त होने ( "\r\n") '\ "\r\n") ' के साथ अभी भी लाइन पर अंतिम वर्ण है।

उदाहरण getline() कार्यान्वयन getline()

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>


#if !(defined _POSIX_C_SOURCE)
typedef long int ssize_t;
#endif

/* Only include our version of getline() if the POSIX version isn't available. */

#if !(defined _POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L

#if !(defined SSIZE_MAX)
#define SSIZE_MAX (SIZE_MAX >> 1)
#endif

ssize_t getline(char **pline_buf, size_t *pn, FILE *fin)
{
  const size_t INITALLOC = 16;
  const size_t ALLOCSTEP = 16;
  size_t num_read = 0;

  /* First check that none of our input pointers are NULL. */
  if ((NULL == pline_buf) || (NULL == pn) || (NULL == fin))
  {
    errno = EINVAL;
    return -1;
  }

  /* If output buffer is NULL, then allocate a buffer. */
  if (NULL == *pline_buf)
  {
    *pline_buf = malloc(INITALLOC);
    if (NULL == *pline_buf)
    {
      /* Can't allocate memory. */
      return -1;
    }
    else
    {
      /* Note how big the buffer is at this time. */
      *pn = INITALLOC;
    }
  }

  /* Step through the file, pulling characters until either a newline or EOF. */

  {
    int c;
    while (EOF != (c = getc(fin)))
    {
      /* Note we read a character. */
      num_read++;

      /* Reallocate the buffer if we need more room */
      if (num_read >= *pn)
      {
        size_t n_realloc = *pn + ALLOCSTEP;
        char * tmp = realloc(*pline_buf, n_realloc + 1); /* +1 for the trailing NUL. */
        if (NULL != tmp)
        {
          /* Use the new buffer and note the new buffer size. */
          *pline_buf = tmp;
          *pn = n_realloc;
        }
        else
        {
          /* Exit with error and let the caller free the buffer. */
          return -1;
        }

        /* Test for overflow. */
        if (SSIZE_MAX < *pn)
        {
          errno = ERANGE;
          return -1;
        }
      }

      /* Add the character to the buffer. */
      (*pline_buf)[num_read - 1] = (char) c;

      /* Break from the loop if we hit the ending character. */
      if (c == '\n')
      {
        break;
      }
    }

    /* Note if we hit EOF. */
    if (EOF == c)
    {
      errno = 0;
      return -1;
    }
  }

  /* Terminate the string by suffixing NUL. */
  (*pline_buf)[num_read] = '\0';

  return (ssize_t) num_read;
}

#endif

बाइनरी फ़ाइल को खोलें और लिखें

#include <stdlib.h>
#include <stdio.h>


int main(void)
{
   result = EXIT_SUCCESS;

   char file_name[] = "outbut.bin";
   char str[] = "This is a binary file example";
   FILE * fp = fopen(file_name, "wb");
   
   if (fp == NULL)  /* If an error occurs during the file creation */
   {
     result = EXIT_FAILURE;
     fprintf(stderr, "fopen() failed for '%s'\n", file_name);
   }
   else
   {
     size_t element_size = sizeof *str;
     size_t elements_to_write = sizeof str;

     /* Writes str (_including_ the NUL-terminator) to the binary file. */
     size_t elements_written = fwrite(str, element_size, elements_to_write, fp); 
     if (elements_written != elements_to_write)
     {
       result = EXIT_FAILURE;
       /* This works for >=c99 only, else the z length modifier is unknown. */
       fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n", 
         elements_written, elements_to_write);
       /* Use this for <c99: *
       fprintf(stderr, "fwrite() failed: wrote only %lu out of %lu elements.\n", 
         (unsigned long) elements_written, (unsigned long) elements_to_write);
        */
     }

     fclose(fp);
   }

   return result;
}

इस कार्यक्रम के माध्यम से बनाता है और बाइनरी रूप में पाठ लिखते हैं fwrite फाइल करने के लिए समारोह output.bin

यदि समान नाम वाली फ़ाइल पहले से मौजूद है, तो उसकी सामग्री को छोड़ दिया जाता है और फ़ाइल को एक नई खाली फ़ाइल के रूप में माना जाता है।

एक बाइनरी स्ट्रीम पात्रों का एक क्रमबद्ध क्रम है जो आंतरिक डेटा को पारदर्शी रूप से रिकॉर्ड कर सकता है। इस मोड में, बाइट्स को प्रोग्राम और फ़ाइल के बीच बिना किसी व्याख्या के लिखा जाता है।

पूर्णांकों को आंशिक रूप से लिखने के लिए, यह ज्ञात होना चाहिए कि फ़ाइल प्रारूप उन्हें बड़े या छोटे-एंडियन प्रारूप में, और आकार (आमतौर पर 16, 32 या 64 बिट्स) की अपेक्षा करता है। बिट शिफ्टिंग और मास्किंग का इस्तेमाल तब बाइट्स को सही क्रम में लिखने के लिए किया जा सकता है। सी में इंटेगर को दो के पूरक प्रतिनिधित्व की गारंटी नहीं है (हालांकि लगभग सभी कार्यान्वयन करते हैं)। सौभाग्य से अहस्ताक्षरित में रूपांतरण को टोमस पूरक के उपयोग की गारंटी दी जाती है। एक द्विआधारी फ़ाइल में एक हस्ताक्षरित पूर्णांक लिखने के लिए कोड इसलिए थोड़ा आश्चर्य होता है।

/* write a 16-bit little endian integer */
int fput16le(int x, FILE *fp)
{
    unsigned int rep = x;
    int e1, e2;

    e1 = fputc(rep & 0xFF, fp);
    e2 = fputc((rep >> 8) & 0xFF, fp);

    if(e1 == EOF || e2 == EOF)
        return EOF;
    return 0;  
}

अन्य फ़ंक्शन आकार और बाइट ऑर्डर के लिए मामूली संशोधनों के साथ समान पैटर्न का पालन करते हैं।

fscanf ()

मान लें कि हमारे पास एक पाठ फ़ाइल है और हम कुछ आवश्यकताओं को करने के लिए उस फ़ाइल के सभी शब्दों को पढ़ना चाहते हैं।

file.txt :

This is just
a test file
to be used by fscanf()

यह मुख्य कार्य है:

#include <stdlib.h>
#include <stdio.h>

void printAllWords(FILE *);

int main(void)
{
  FILE *fp;

  if ((fp = fopen("file.txt", "r")) == NULL) {
      perror("Error opening file");
      exit(EXIT_FAILURE);
  }

  printAllWords(fp);

  fclose(fp);
  
  return EXIT_SUCCESS;
}

void printAllWords(FILE * fp)
{
    char tmp[20];
    int i = 1;

    while (fscanf(fp, "%19s", tmp) != EOF) {
        printf("Word %d: %s\n", i, tmp);
        i++;
    }
}

उत्पादन होगा:

Word 1: This 
Word 2: is 
Word 3: just
Word 4: a 
Word 5: test
Word 6: file
Word 7: to
Word 8: be 
Word 9: used
Word 10: by
Word 11: fscanf()

एक फ़ाइल से लाइनें पढ़ें

stdio.h हैडर fgets() फ़ंक्शन को परिभाषित करता है। यह फ़ंक्शन स्ट्रीम से एक पंक्ति पढ़ता है और इसे एक निर्दिष्ट स्ट्रिंग में संग्रहीत करता है। फ़ंक्शन तब स्ट्रीम से पाठ पढ़ना बंद कर देता है जब या तो n - 1 वर्ण पढ़े जाते हैं, नई पंक्ति वर्ण ( '\n' ) पढ़ी जाती है या फ़ाइल (EOF) के अंत तक पहुँच जाती है।

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

#define MAX_LINE_LENGTH 80

int main(int argc, char **argv)
{
    char *path;
    char line[MAX_LINE_LENGTH] = {0};
    unsigned int line_count = 0;
    
    if (argc < 1)
        return EXIT_FAILURE;
    path = argv[1];
    
    /* Open file */
    FILE *file = fopen(path, "r");
    
    if (!file)
    {
        perror(path);
        return EXIT_FAILURE;
    }
    
    /* Get each line until there are none left */
    while (fgets(line, MAX_LINE_LENGTH, file))
    {
        /* Print each line */
        printf("line[%06d]: %s", ++line_count, line);
        
        /* Add a trailing newline to lines that don't already have one */
        if (line[strlen(line) - 1] != '\n')
            printf("\n");
    }
    
    /* Close file */
    if (fclose(file))
    {
        return EXIT_FAILURE;
        perror(path);
    }
}

प्रोग्राम को एक तर्क के साथ कॉल करना जो निम्न पाठ वाली फ़ाइल का पथ है:

This is a file
  which has
multiple lines
    with various indentation,
blank lines



a really long line to show that the line will be counted as two lines if the length of a line is too long to fit in the buffer it has been given,
  and punctuation at the end of the lines.

निम्नलिखित उत्पादन में परिणाम होगा:

line[000001]: This is a file
line[000002]:   which has
line[000003]: multiple lines
line[000004]:     with various indentation,
line[000005]: blank lines
line[000006]: 
line[000007]: 
line[000008]: 
line[000009]: a really long line to show that the line will be counted as two lines if the le
line[000010]: ngth of a line is too long to fit in the buffer it has been given,
line[000011]:  and punctuation at the end of the lines.
line[000012]: 

यह बहुत ही सरल उदाहरण एक निश्चित अधिकतम लाइन लंबाई की अनुमति देता है, जैसे कि लंबी लाइनें प्रभावी रूप से दो लाइनों के रूप में गिना जाएगा। fgets() फ़ंक्शन के लिए आवश्यक है कि कॉलिंग कोड मेमोरी को उस लाइन के लिए गंतव्य के रूप में उपयोग करने के लिए प्रदान करे जो पढ़ी जाती है।

POSIX getline() फ़ंक्शन को उपलब्ध कराता है जो किसी भी लम्बाई (जब तक पर्याप्त मेमोरी है) की एक पंक्ति के लिए बफर को बड़ा करने के लिए आंतरिक रूप से मेमोरी आवंटित करता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow