Wikipedia says it's called a quine and someone gave the code below:
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}
But, obviously you have to add
#include <stdio.h> //corrected from #include <stdlib.h>
so that the printf() could work.
Literally, since the above program did not print #include <stdio.h>, it is not a solution (?)
I am confused about the literal requirement of "print its own source code", and any purpose of this kind of problems, especially at interviews.
The main purpose of interview questions about quine programs is usually to see whether you've come across them before. They are almost never useful in any other sense.
The code above can be upgraded modestly to make a C99-compliant program (according to GCC), as follows:
Compilation
/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes \
-Wstrict-prototypes -Wold-style-definition quine.c -o quine
Code
#include <stdio.h>
char*s="#include <stdio.h>%cchar*s=%c%s%c;%cint main(void){printf(s,10,34,s,34,10,10);}%c";
int main(void){printf(s,10,34,s,34,10,10);}
Note that this assumes a code set where " is code point 34 and newline is code point 10. This version prints out a newline at the end, unlike the original. It also contains the #include <stdio.h> that is needed, and the lines are almost short enough to work on SO without a horizontal scroll bar. With a little more effort, it could undoubtedly be made short enough.
Test
The acid test for the quine program is:
./quine | diff quine.c -
If there's a difference between the source code and the output, it will be reported.
An almost useful application of "quine-like" techniques
Way back in the days of my youth, I produced a bilingual "self-reproducing" program. It was a combination of shell script and Informix-4GL (I4GL) source code. One property that made this possible was that I4GL treats { ... } as a comment, but the shell treats that as a unit of I/O redirection. I4GL also has #...EOL comments, as does the shell. The shell script at the top of the file included data and operations to regenerate the complex sequence of validation operations in a language that does not support pointers. The data controlled which I4GL functions we generated and how each one was generated. The I4GL code was then compiled to validate the data imported from an external data source on a weekly basis.
If you ran the file (call it file0.4gl) as a shell script and captured the output (call that file1.4gl), and then ran file1.4gl as a shell script and captured the output in file2.4gl, the two files file1.4gl and file2.4gl would be identical. However, file0.4gl could be missing all the generated I4GL code and as long as the shell script 'comment' at the top of the file was not damaged, it would regenerate a self-replicating file.
The trick here is that most compilers will compile without requiring you to include stdio.h.
They will usually just throw a warning.
A quine has some depth roots in fixed point semantics related to programming languages and to executions in general. They have some importance related to theoretical computer science but in practice they have no purpose.
They are a sort of challenge or tricks.
The literal requirement is just you said, literal: you have a program, its execution produces itself as the output. Nothing more nor less, that's why it's considered a fixed point: the execution of the program through the language semantics has itself as its ouput.
So if you express the computation as a function you'll have that
f(program, environment) = program
In the case of a quine the environment is considered empty (you don't have anything as input neither precomputed before)
You can also define printf's prototype by hand.
const char *a="const char *a=%c%s%c;int printf(const char*,...);int main(){printf(a,34,a,34);}";int printf(const char*,...);int main(){printf(a,34,a,34);}
Here's a version that will be accepted by C++ compilers:
#include<stdio.h>
const char*s="#include<stdio.h>%cconst char*s=%c%s%c;int main(int,char**){printf(s,10,34,s,34);return 0;}";int main(int,char**){printf(s,10,34,s,34);return 0;}
test run:
$ /usr/bin/g++ -o quine quine.cpp
$ ./quine | diff quine.cpp - && echo 'it is a quine' || echo 'it is not a quine'
it is a quine
The string s contains mostly a copy of the source, except for the content of s itself - instead it has %c%s%c there.
The trick is that in the printf call, the string s is used both as format and as the replacement for the %s. This causes printf to put it also into the definition of s (on the output text, that is)
the additional 10 and 34s correspond to the linefeed and " string delimiter. They are inserted by printf as replacements of the %cs, because they would require an additional \ in the format-string, which would cause the format- and replacement-string to differ, so the trick wouldn't work anymore.
Quine (Basic self-relicating code in c++`// Self replicating basic code
[http://www.nyx.net/~gthompso/quine.htm#links]
[https://pastebin.com/2UkGbRPF#links]
// Self replicating basic code
#include <iostream> //1 line
#include <string> //2 line
using namespace std; //3 line
//4 line
int main(int argc, char* argv[]) //5th line
{
char q = 34; //7th line
string l[] = { //8th line ---- code will pause here and will resume later in 3rd for loop
" ",
"#include <iostream> //1 line ",
"#include <string> //2 line ",
"using namespace std; //3 line ",
" //4 line ",
"int main(int argc, char* argv[]) //5th line ",
"{",
" char q = 34; //7th line ",
" string l[] = { //8th line ",
" }; //9th resume printing end part of code ", //3rd loop starts printing from here
" for(int i = 0; i < 9; i++) //10th first half code ",
" cout << l[i] << endl; //11th line",
" for(int i = 0; i < 18; i++) //12th whole code ",
" cout << l[0] + q + l[i] + q + ',' << endl; 13th line",
" for(int i = 9; i < 18; i++) //14th last part of code",
" cout << l[i] << endl; //15th line",
" return 0; //16th line",
"} //17th line",
}; //9th resume printing end part of code
for(int i = 0; i < 9; i++) //10th first half code
cout << l[i] << endl; //11th line
for(int i = 0; i < 18; i++) //12th whole code
cout << l[0] + q + l[i] + q + ',' << endl; 13th line
for(int i = 9; i < 18; i++) //14th last part of code
cout << l[i] << endl; //15th line
return 0; //16th line
} //17th line
Not sure if you were wanting the answer on how to do this. But this works:
#include <cstdio>
int main () {char n[] = R"(#include <cstdio>
int main () {char n[] = R"(%s%c"; printf(n, n, 41); })"; printf(n, n, 41); }
If you are a golfer, this is a more minified version:
#include<cstdio>
int main(){char n[]=R"(#include<cstdio>
int main(){char n[]=R"(%s%c";printf(n,n,41);})";printf(n,n,41);}
My version without using %c:
#include <stdio.h>
#define S(x) #x
#define P(x) printf(S(S(%s)),x)
int main(){char y[5][300]={
S(#include <stdio.h>),
S(#define S(x) #x),
S(#define P(x) printf(S(S(%s)),x)),
S(int main(){char y[5][300]={),
S(};puts(y[0]);puts(y[1]);puts(y[2]);puts(y[3]);P(y[0]);putchar(',');puts(S());P(y[1]);putchar(',');puts(S());P(y[2]);putchar(',');puts(S());P(y[3]);putchar(',');puts(S());P(y[4]);puts(S());fputs(y[4],stdout);})
};puts(y[0]);puts(y[1]);puts(y[2]);puts(y[3]);P(y[0]);putchar(',');puts(S());P(y[1]);putchar(',');puts(S());P(y[2]);putchar(',');puts(S());P(y[3]);putchar(',');puts(S());P(y[4]);puts(S());fputs(y[4],stdout);}
/* C/C++ code that shows its own source code without and with File line number and C/C++ code that shows its own file path name of the file. With Line numbers */
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define SHOW_SOURCE_CODE
#define SHOW_SOURCE_FILE_PATH
/// Above two lines are user defined Macros
int main(void) {
/* shows source code without File line number.
#ifdef SHOW_SOURCE_CODE
// We can append this code to any C program
// such that it prints its source code.
char c;
FILE *fp = fopen(__FILE__, "r");
do
{
c = fgetc(fp);
putchar(c);
}
while (c != EOF);
fclose(fp);
// We can append this code to any C program
// such that it prints its source code.
#endif
*/
#ifdef SHOW_SOURCE_FILE_PATH
/// Prints location of C this C code.
printf("%s \n",__FILE__);
#endif
#ifdef SHOW_SOURCE_CODE
/// We can append this code to any C program
/// such that it prints its source code with line number.
unsigned long ln = 0;
FILE *fp = fopen(__FILE__, "r");
int prev = '\n';
int c; // Use int here, not char
while((c=getc(fp))!=EOF) {
if (prev == '\n'){
printf("%05lu ", ++ln);
}
putchar(c);
prev = c;
}
if (prev != '\n') {
putchar('\n'); /// print a \n for input that lacks a final \n
}
printf("lines num: %lu\n", ln);
fclose(fp);
/// We can append this code to any C program
/// such that it prints its source code with line number.
#endif
return 0;
}
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
Our instructor requires us to input data into code in the following ways:
1.Random mode
Run with graphs generated by random number generator. The command line for
this mode is:
$ mst –r n d
// run in a random connected graph with n vertices and d% of density.
// See Performance measurements section for details.
2.User Input mode
$mst -s file-name // read the input from a file ‘file-name’ for simple scheme
$mst -f file-name // read the input from a file ‘file-name’ for f-heap scheme
At present I have written the code and compiled it using g++:
g++ -o mst.o mst.cpp
I am taking input from the file like this:
./mst.o < data.txt
However, I don't know how to go about satisfying the above requirements.
An application starts in main like this:
int main(int argc, char* argv[])
These are the command line arguments.
You can print them out if you want:
int main(int argc, char* argv[])
{
std::cout << "Application: " << argv[0] << "\n";
for(int loop =1 ;loop < argc; ++loop)
{
std::cout << "\tArg: " << loop << " Value: " << argv[loop] << "\n";
}
}
You need to check the argc and argv parameters to main. If argv is large enough, check argv[1] to see if it's one of the switches you need to handle. If it is then decode the other argv for the numbers or filenames that you need. argv[0] is generally the name of the executable and isn't used.
I have following program and i am passing it 2 arguments at the command line as shown below. I was expecting the argc to be 3, but it prints it as 6. why?
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void usage();
int main(int argc, char *argv[])
{
cout << argc << endl;
if (argc != 3)
usage();
string regex = argv[1];
string searchString = argv[2];
cout << "regex: " << regex << " . searchString: " << searchString << endl;
return 0;
}
void usage()
{
cout << "Usage: ./stringmatch <regex> <searchString>" << endl;
exit(1);
}
Command line:
[jim#cola c++]$ ./stringmatch [yyyy\d\d\d]* yyyy1234
6
Usage: ./stringmatch <regex> <searchString>
Your shell is expanding the glob pattern [yyyy\d\d\d]* so the actual number of arguments this results in depends on the contents of the current directory!
The [yyyy\d\d\d] becomes a character class matching the characters y and d, and the * matches anything that follows, so I'm guessing your current directory has 4 files that start with y or d. To see what it expands to, use echo:
$ echo [yyyy\d\d\d]*
To make it work as intended, quote the argument:
$ ./stringmatch '[yyyy\d\d\d]*' yyyy1234
[yyyy\d\d\d]* is expanded by the shell into multiple file names that match the pattern. Quote it to get 3.
The shell resolves your command line to
./stringmatch [yd]* yyyy1234
which gives all files starting with either y or d plus yyyy1234. So if you have 4 files starting with either y and d plus yyyy1234 plus ./stringmatch will give exactly 6.
See Filename Expansion and Pattern Matching for more information.
If you want just two arguments you must quote the first one with single or double quotes
./stringmatch '[yyyy\d\d\d]*' yyyy1234
Because your shell is expanding the arguments - wrap them in '' to prevent this.
How would you use an if/then statement using argv[], upon the option/parameter entered?
For example, a.out -d 1 sample.txt versus a.out -e 1 sample.txt.
int main (int argc, char *argv[])
{
ifstream infile(argv[3]);
int c;
int number = 0;
int count = 0;
while ( infile.good() ) {
if (argv[1] == "-d")
{
c = infile.get();
number = atoi(argv[2]);
if (number == count)
{
cout.put(c);
count = 0;
}
else
count++;
}
if (argv[1] == "-e")
{
cout << "entered -e" << endl; //testing code
}
}//end while
}//end main
You can't use the equality operator to compare C-style strings, you have to use std::strcmp:
if (std::strcmp(argv[1], "-d") == 0)
The reason behind that is that the == operator compares the pointers not what they point to.
I hope you want to check the input parameter -d or -e, right?
if that is the case please use strcmp()
if (!strcmp(argv[1],"-d"))
{
count++;
printf("\ncount=%d",count);
}
if (!strcmp(argv[1],"-e"))
{
printf("entered -e"); //testing code
}
The first error is in the very first line of main:
ifstream infile(argv[3]);
You cannot write that because there is no third argument. When you invoke your program like this:
a.out -d 1 < sample.txt
then the command line that the program sees looks like this:
argv[0] = "a.out"
argv[1] = "-d"
argv[2] = "1"
The < sample.txt, by contrast, is interpreted by the shell directly, and the file is streamed to the standard input of your program – and there’s nothing you can do to change that, inside your program.
As for the parsing itself, don’t do it inside the loop which reads the file, do it before and set appropriate flags.
For the actual parsing I’d suggest using a library to spare you a lot of pain. The standard Unix tool is getopt but that’s only got a C interface. There are several C++ libraries, amongst them Boost.Program_Options which is a tad too complex for my taste, though.
The argc/argv comes from C and is rather cumbersome to use, so when more than basic argument passing is done, you can transform the arguments to a vector of strings and work in a C++ style:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
main(int argc, char* argv[])
{
std::vector<std::string> args;
std::transform(argv+1, argv+argc, std::back_inserter(args), [](char* arg){ return std::string(arg); });
if (args.at(1) == "-d") { std::cout << "Arg 1 = -d" << "\n"; }
for (auto& arg: args) { std::cout << "arg: " << arg << "\n"; }
}
Still, you need to check that the argument is present. If this is a basic tool and it is acceptable that the tool aborts when the parameter is not present, then you can access args elements with args.at(x) instead of args[x]
Or check this SO question for an argument parser.
char argv[] is an array of char *
so
if (string(argv[1]) == "-d")
I currently have a c++ Linux program that reads a parameter "P" from a file and loads it in RAM for further operations. The file has the following line :
P = 123
I would like the program to take P from shell input instead of the file. I am open to all options, as long as I can manually enter P while connected in SSH.
What I have in mind is something like an input prompt :
sudo myprogram start
enter P value : (I would manually enter "123" here)
Or maybe an argument :
sudo myprogram start 123
It must be simple to do but I do not know how, so any help is greatly appreciated !
If this is the only data that the file has then the file operation is needless.
Simply pass 123 (or whatever) to your C++ program and convert the string into integer.
Assuming you pass the integer as the second argument then:
int p = atoi(argv[2]);
A better option is to use strtol:
char *s, *ptr;
s = argv[1];
int p = strtol(s, &ptr, 10);
If you can't make changes to the C++ code then simply do:
echo "P = 123" > file && myprogram start
If your file has more content and you can't simply do echo then, replace the existing line with new value:
sed -i "s/P = [0-9]*/P = 123/" file && myprogram start
First version (enter from keyboard):
echo -n "enter P value: "
read P
Second version (pass as shell script argument):
P=$1
Third version (learn bash/shell programming):
Advanced Bash-Scripting Guide
BASH Programming - Introduction HOW-TO
and many others
This is basic C++. Take a look at the sample code below or visit the site I copied it from.
#include <iostream>
// When passing char arrays as parameters they must be pointers
int main(int argc, char* argv[]) {
if (argc < 5) { // Check the value of argc. If not enough parameters have been passed, inform user and exit.
std::cout << "Usage is -in <infile> -out <outdir>\n"; // Inform the user of how to use the program
std::cin.get();
exit(0);
} else { // if we got enough parameters...
char* myFile, myPath, myOutPath;
std::cout << argv[0];
for (int i = 1; i < argc; i++) { /* We will iterate over argv[] to get the parameters stored inside.
* Note that we're starting on 1 because we don't need to know the
* path of the program, which is stored in argv[0] */
if (i + 1 != argc) // Check that we haven't finished parsing already
if (argv[i] == "-f") {
// We know the next argument *should* be the filename:
myFile = argv[i + 1];
} else if (argv[i] == "-p") {
myPath = argv[i + 1];
} else if (argv[i] == "-o") {
myOutPath = argv[i + 1];
} else {
std::cout << "Not enough or invalid arguments, please try again.\n";
Sleep(2000);
exit(0);
}
std::cout << argv[i] << " ";
}
//... some more code
std::cin.get();
return 0;
}
}
Don't you simply want to be prompted, within your C++ program, to input the value?
If that is what you want, this simple code will do the job:
#include <iostream>
int main(int argc, char **argv) {
int p = 0;
std::cout << "Enter P value: ";
std::cin >> p;
std::cout << "Entered value: " << p << std::endl;
return 0;
}