C Program to Print Its Own Source Code

Printing the source code of a program as its output is an interesting programming exercise known as a quine. In this article, we will cover various methods to create a C program that prints its own source code. We will explore multiple examples, each demonstrating a different approach to solve the problem. Additionally, we will discuss the prerequisites, provide detailed explanations for each example, and conclude with a summary of what we’ve learned.

Prerequisites

Before we delve into the examples, ensure you have the following prerequisites:

  • A C compiler (such as GCC)
  • A text editor or IDE for writing your C code
  • Basic understanding of C programming concepts, especially file handling and string manipulation

1. Creating a Quine in C

In this section, we will look at several methods to create a C program that prints its own source code.

1.1 Using String Literals

Example 1: Print Source Code Using String Literals

This method uses string literals to store the source code and print it.

Code

C
#include <stdio.h>

int main() {
    char *source = "#include <stdio.h>\n\nint main() {\n    char *source = \"%s\";\n    printf(source, source);\n    return 0;\n}\n";
    printf(source, source);
    return 0;
}

Explanation

  • Include necessary header: #include <stdio.h> for input/output functions.
  • Store the source code in a string literal: Use a character array to store the source code.
  • Print the source code: Use printf to print the string literal.
  • Output the result: The program prints its own source code.

Output

C
#include <stdio.h>

int main() {
    char *source = "#include <stdio.h>\n\nint main() {\n    char *source = \"%s\";\n    printf(source, source);\n    return 0;\n}\n";
    printf(source, source);
    return 0;
}

1.2 Using File Handling

Example 2: Print Source Code Using File Handling

This method uses file handling to read the source code from the file and print it.

Code

C
#include <stdio.h>

int main() {
    FILE *fp;
    char ch;

    fp = fopen(__FILE__, "r");

    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
    }

    fclose(fp);
    return 0;
}

Explanation

  • Include necessary header: #include <stdio.h> for input/output functions.
  • Open the source code file: Use fopen with __FILE__ to open the current file.
  • Read and print the file: Use fgetc to read characters from the file and putchar to print them.
  • Close the file: Use fclose to close the file after reading.

Output

C
#include <stdio.h>

int main() {
    FILE *fp;
    char ch;

    fp = fopen(__FILE__, "r");

    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }

    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
    }

    fclose(fp);
    return 0;
}

1.3 Using Recursive Function

Example 3: Print Source Code Using Recursive Function

This method uses a recursive function to print the source code.

Code

C
#include <stdio.h>

void printSource(const char *source, int index);

int main() {
    const char *source = "#include <stdio.h>\n\nvoid printSource(const char *source, int index);\n\nint main() {\n    const char *source = \"%s\";\n    printSource(source, 0);\n    return 0;\n}\n\nvoid printSource(const char *source, int index) {\n    if (source[index] == '\\0') return;\n    putchar(source[index]);\n    printSource(source, index + 1);\n}\n";
    printSource(source, 0);
    return 0;
}

void printSource(const char *source, int index) {
    if (source[index] == '\0') return;
    putchar(source[index]);
    printSource(source, index + 1);
}

Explanation

  • Include necessary header: #include <stdio.h> for input/output functions.
  • Declare a recursive function: void printSource(const char *source, int index) to print the source code.
  • Store the source code in a string literal: Use a character array to store the source code.
  • Call the recursive function: printSource(source, 0) prints the source code.
  • Output the result: The program prints its own source code.

Output

C
#include <stdio.h>

void printSource(const char *source, int index);

int main() {
    const char *source = "#include <stdio.h>\n\nvoid printSource(const char *source, int index);\n\nint main() {\n    const char *source = \"%s\";\n    printSource(source, 0);\n    return 0;\n}\n\nvoid printSource(const char *source, int index) {\n    if (source[index] == '\\0') return;\n    putchar(source[index]);\n    printSource(source, index + 1);\n}\n";
    printSource(source, 0);
    return 0;
}

void printSource(const char *source, int index) {
    if (source[index] == '\0') return;
    putchar(source[index]);
    printSource(source, index + 1);
}

1.4 Using Macros

Example 4: Print Source Code Using Macros

This method uses macros to define the source code and print it.

Code

C
#include <stdio.h>

#define SOURCE "#include <stdio.h>\n\n#define SOURCE \"%s\"\n\nint main() {\n    printf(SOURCE, SOURCE);\n    return 0;\n}\n"

int main() {
    printf(SOURCE, SOURCE);
    return 0;
}

Explanation

  • Include necessary header: #include <stdio.h> for input/output functions.
  • Define the source code using a macro: Use #define to define the source code.
  • Print the source code: Use printf to print the macro.
  • Output the result: The program prints its own source code.

Output

C
#include <stdio.h>

#define SOURCE "#include <stdio.h>\n\n#define SOURCE \"%s\"\n\nint main() {\n    printf(SOURCE, SOURCE);\n    return 0;\n}\n"

int main() {
    printf(SOURCE, SOURCE);
    return 0;
}

1.5 Using a Combination of Macros and String Literals

Example 5: Print Source Code Using Macros and String Literals

This method combines macros and string literals to print the source code.

Code

C
#include <stdio.h>

#define QUOTE(...) #__VA_ARGS__
#define SOURCE QUOTE(#include <stdio.h>\n\n#define QUOTE(...) #__VA_ARGS__\n#define SOURCE QUOTE(%s)\n\nint main() {\n    printf(SOURCE, SOURCE);\n    return 0;\n}\n)

int main() {
    printf(SOURCE, SOURCE);
    return 0;
}

Explanation

  • Include necessary header: #include <stdio.h> for input/output functions.
  • Define macros for quoting and the source code: Use #define to define macros.
  • Print the source code: Use printf to print the macro.
  • Output the result: The program prints its own source code.

Output

C
#include <stdio.h>

#define QUOTE(...) #__VA_ARGS__
#define SOURCE QUOTE(#include <stdio.h>\n\n#define QUOTE(...) #__VA_ARGS__\n#define SOURCE QUOTE(%s)\n\nint main() {\n    printf(SOURCE, SOURCE);\n    return 0;\n}\n)

int main() {
    printf(SOURCE, SOURCE);
    return 0;
}

2. Conclusion

In this article, we explored various methods to create a C program that prints its own source code: using string literals, using file handling, using recursive functions, using macros, and using a combination of macros and string literals. Each method demonstrates different aspects of handling strings, file operations, and macros in C programming. By understanding these methods, you can choose the one that best fits your specific needs and enhance your skills in advanced programming concepts in C.