Quine Program Example in C [duplicate] - c

This question already has answers here:
C/C++ program that prints its own source code as its output
(10 answers)
Closed 3 years ago.
In my course slides, I have this example but without much explanation:
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
I understand what quine programs in general mean but I do not quite understand what's happening in the code above. This is the output I get if I run it:
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
But how is it reproducing its own code? I don't really understand how the output is produced.

Start by writing it out in a way that'll be clearer (not changing anything but the layout):
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";
main()
{
printf(f,34,f,34,10);
}
So we see a main function as we'd expect (it should return an int but you're allowed to get away with not in C; likewise for no function arguments).
And before that, a regular string. It's a funny-looking string, but it is not really that different to char*f="fish";.
Okay, so what if we expand the printf by putting the string in there by hand?
printf("char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c" ,34,f,34,10);
We can see that it's going to print out some guff, and substitute in some values along the way. They are:
First %c : 34 (the ASCII code for " (quotes))
First %s : 'f' (our string, once again)
Second %c : 34 (" again)
Third %c : 10 (the ASCII code for Newline)
Let's substitute those all in then too (though I've replaced the contents of the string with <the string>, and "'s with \"'s to make it actually work as a standalone statement):
main()
{
printf("char*f=\"<the string>\";main(){printf(f,34,f,34,10);}\n");
}
Well look at that! main simply prints out the line we first started with. Hurrah!
Edited to add:
Although I've basically spelled out the answer for you, there is still a puzzle remaining. Consider for yourself why we bother substituting in the 34, f, 34, 10, rather than just putting them directly into the string like I did in my final code.

Related

Why is a strange character appearing on my screen? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 months ago.
Improve this question
I am new to C, I have written a very simple program to get the first name and surname, here is my code...
#include <stdio.h>
#include <conio.h>
int main(){
int num,bankpin;
char fn[20],sn[20];
printf("Welcome to authorization. We ill now begin the process");
printf("\nFirst, please enter your first name: ");
scanf(" %s",fn);
printf("\nEnter your surname: ");
scanf(" %s",sn);
printf("\nWelcome to the system %c %c",&fn,&sn);
return 0;
}
Welcome to authorization. We ill now begin the process
First, please enter your first name: A
Enter your surname: A
Welcome to the system α
Why is this strange "a" appearing on my screen instead of "A A"?
In fact it appears on my screen even if I try a different combination of letters
I have even tried recompiling the code
I'm guessing this is because you are trying to print &fn, which is a pointer, as char. You're basically telling the program to interpret the address o as a symbol code.
Try changing the
printf("\nWelcome to the system %c %c",&fn,&sn) to
printf("\nWelcome to the system %s %s",fn,sn)
Short answer
You are sending the array pointer's address as an argument, and telling printf to interpret it as a single char, resulting in undefined behavior. The fix is to replace the line
printf("\nWelcome to the system %c %c",&fn,&sn);
with
printf("\nWelcome to the system %s %s",fn,sn);
Long answer
The weird character is due to your code reading an unintended value, and trying to interpret it. If you run your code a few times, you will find that you don't always get this symbol, but many other ones, including nothing at all (seemingly). What is going here ?
The short answer is that you are misinforming the printf function by giving her a false symbol and a false value. Let's look at a similar example :
char myString[20] = "Hello!";
printf("%c", &myString);
In this snippet we create an array of characters, which actually means creating a pointer of char* type, and allocating its size (here to 20). Pointers are often confusing when starting with C, but they are in principle pretty simple : they are simply variables that, instead of containing a value, contain an address. Since arrays in C store their value sequentially, that is one after the other, it makes quite a lot of sense to have them be pointers : if you know where the array starts, and that its members are spaced evenly, it makes it quite easy to go over the array.
So since your array is a pointer, reading it directly will print something along the lines of "0x7ffc5a6dbb70". Putting '&' before it gives a very similar result : this operator consists in asking for the address of a variable, which is then in your code transmitted to the printf as an argument.
This doesn't make any sense there : a char is, in C, behind the scene, actually an integer variable with very small capacity, from 0 to 255 to be precise. For example the two lines in the following snippet produce the same result :
printf("%c", 'a');
printf("%c", 97);
Now you see what is happening in the original printf : the function is expecting to receive a very small integer to convert to one character, and instead receives an address, which is the reason why the output is so weird. Since addresses change basically at every run of the code, that is also the reason why the output changes very often.
You thus need to adapt the information in the printf function. First, inform that you wish to print a char array with the symbol "%s". This will make the function expect to receive a pointer to the first element of a char array, which it will then iterate over. Thus, as argument, you need to send this pointer, that you directly have in the form of the myString variable.
Thus running
char myString[20] = "Hello!";
printf("%s", myString);
prints 'Hello!', as expected :)
The funcion scanf is a little tricky, please delete the leading space, inside quotes only include what are you expecting to receive, ever.
scanf("%s",fn);
The printf function needs %s, same as scanf, to deal with string, later you don't need the & operator in this case.
printf("\nWelcome to the system %s %s",fn,sn);

Comparing two different strings with the same name in c

I am learning how to code in c right now, as such, the next step in my agenda was learning how to code recursively. For this, I tried to write code that takes a users input, then reverses it recursively and tell you if its a palindrome or not.
The current issues number 3, The first is whether or not I have even been writing recursively, the second pertains to which string comparison I have to do in this part of the code to determine if its a palindrome or not:
int main(){
//char stringran[256];
//char done;
char str1[1024];
int size;
printf("Enter a string to reverse, or done to exit program: ");
scanf("%s", str1);
size = strlen(str1);
printf("The string you enterred is: %s\n", str1);
reverse(str1, 0, size - 1);
printf("The string after reversing is: %s\n", str1);
//the if-else statement below is the issue, currently i have a placeholder//
if(str1 == str1){
printf("The string is a palindrome");
}
else{
printf("The string is not a palindrome");
}
Lastly, if I wish to loop the code so that it keeps asking the initial question after a string is input (Enter a string to reverse, or done to exit program), how would I go about doing it? Would it be a for-loop or a while-loop?.
Full code with output:
https://onlinegdb.com/Sk_vTLJp7
"The current issues number 3"
"The first is whether or not I have even been writing recursively."
Yes, your reverse() function is recursive. Any function that calls itself is recursive. However, it is very easy to write a recursive function that operates incorrectly, does not handle appropriate cases very well, mucks up memory management, or runs on infinitely. Programming in C demands great care; writing recursive functions demands even greater care.
As noted in the comments, detecting a palindrome does not require a recursive function. As an exercise, I suppose it's alright, but (1) if you were faced with this problem for real, you'd be much better off approaching it quite differently, and (2) there are much better problems for learning recursion, because of being both simpler and more suited to a recursive approach. Google is your friend here.
"which string comparison I have to do in this part of the code to determine if its a palindrome or not"
The main thing you need to do is compare two things that might be different. As the comments point out str1 == str1 is always true. You point out that this is placeholder code (so that it compiles). Better placeholder code would be:
if (1) { // placeholder code so that it compiles
That would have eliminated quite a bit of confusion.
As for the comparison you need to do, just make a copy of str1 before modifying it. Then, compare the pre-modified copy with the modified value. But be sure you know what you are doing when you make a copy of str1. Since it wasn't already obvious to you that you need to do this, it might not be obvious to you how to do this. It's one of the pitfalls of C that it's easy to get this wrong. Again, Google will help you here.
"if I wish to loop the code so that it keeps asking the initial question after a string is input, how would I go about doing it? Would it be a for-loop or a while-loop?"
Either would work, since it's trivial to write a for loop that acts like a while loop. The real question is, under what circumstances would you break out of the loop? The answer to that question will point you to both the best type of loop, and the loop condition to give it.

how to print formatted output on terminal using C?

I have written a code for a Library system in C. And I want to show the output in following manner on terminal on Linux. I tried with "\t" but the output gets disturbed when the string size varies. I want to print it in fixed manner no matter what string size comes.
I want to print output like below-
I tried to print this using "\t" but the format gets disturbed when the string length of book or author gets smaller or larger. Can somebody help me with this??
Print with fixed character size. Here it is 7,11 and 10 for columns. Refer this for more details this
printf("Column1 Column2 Column3\n");
printf("%7d%11s%10d\n", 100, "String1", 9348);
printf("%7d%11s%10d\n", 23, "String2", 214);
use printf like this :
printf("%-25s|\n", "a string");
printf("%-25s|\n", "another string");
(the - in %-25s is use to left-justifies your text)
not a linux user (hope we are talking about monospace output) but my experienceis that tab has usually configurable size so if you format for 6 character length and someone have 4 character tab the result will be bad. The safest is to use spaces. You can use formated output like:
printf("float number: 8.3%f",7.56);
But that is not always a good choice for example sometimes negative sign mess up things ...
I usually handle such formatting my self with use of string variables:
line = ""
item = "single unformated text value"
compute length of item
add missing spaces (before or after) to line or item
add item to line
loop #2 for all items
output line
loop #1 for all lines

Starting a new line of text in C

I only have about 1 week of experience in coding, so I've got a lot to learn. I am currently trying to finish an assignment I have in my C class where I have to write a script that can output *s all around the text Welcome to C Programming.
I have managed to complete the first part of the assignment with the code I wrote below, but I can't seem to figure out how to get the *s above and below the text. There wasn't anything mentioned in my notes or lectures either so I'm pretty lost at the moment.
#include <stdio.h>
int main (void)
{
printf ("** Welcome to C Programming **");
return 0;
}
I work on a Mac if that helps. Thanks to anyone that can help me figure this out.
Edit: I added the new line tag and it's working now! Thank you everyone for your input. I am going to try practicing with all of the methods mentioned after I submit my assignment.
You can use the '\n' escape sequence to represent a newline (i.e. line-break) in your printf calls. Since your IDE/code editor most likely uses a monospaced font it should be pretty easy to align the * characters properly:
printf ("******************************\n");
printf ("** Welcome to C Programming **\n");
printf ("******************************\n");
Or, if you wanted to put the whole thing in a single printf call, you can use the \ character followed by a newline in a string literal to break the representation of the string in your editor over multiple lines:
printf (
"******************************\n \
** Welcome to C Programming **\n \
******************************\n"
);
Or even:
printf ("******************************\n"
"** Welcome to C Programming **\n"
"******************************\n");
There is a character for that. It's called "newline". You can't put it directly in the string because that would create a new line in the source code, but inside quotes in C you can produce it with \n.
Alternatively, instead of printf you could use puts, which prints a new line after the string. For this special case this may even be a better solution, since you are not using any of printf's features (the formatting).
As someone in the comments already mentioned - put the \n (new line character) in the text where you want a new line to occur. E.G.
printf("****\nWelcome to C Programming\n****");
****
Welcome to C Programming
****
#include <stdio.h>
int main (void)
{
printf ("******************************\n");
printf ("** Welcome to C Programming **\n");
printf ("******************************\n");
return 0;
}

How does this quine work?

I just came across this quine question, but no one really went into how it works: C/C++ program that prints its own source code as its output
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}
What I especially don't understand is the following has the same output even though I changed the ints:
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,5,s,11);}
It still prints the 34s! Can someone walk me through this step by step?
Let's start by formatting the code to span multiple lines. This breaks the fact that it's a quine, but makes it easier to see what's happening:
char* s = "char*s=%c%s%c;main(){printf(s,34,s,34);}";
main() {
printf(s, 34, s, 34);
}
Essentially, this is a declaration of a string s that's a printf-formatted string, followed by a declaration of a function main that invokes printf on four arguments. (This definition of main uses the old-fashioned "implicit int" rule in C where functions are assumed to have int as a return type unless specified otherwise. I believe this is currently deprecated in C and know for certain that this is not legal C++ code.)
So what exactly is this printf call doing? Well, it might help to note that 34 is the ASCII code for a double-quote, so the line
printf(s, 34, s, 34);
is essentially
printf(s, '"', s, '"');
This means "print the string s with arguments ", s, and "." So what's s? It's shown here:
char* s = "char*s=%c%s%c;main(){printf(s,34,s,34);}";
This follows a common self-reference trick. Ignoring the %c%s%c part, this is basically a string representation of the rest of the program. The %c%s%c part occurs at the point where it becomes self-referential.
So what happens if you call printf(s, '"', s, '"')? This will fill in the placeholder %c%s%c with "char*s=%c%s%c;main(){printf(s,34,s,34);}", which is the string contents of the string s. Combined with the rest of the string s, this therefore proints
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);";
which is the source code of the program. I think this is kinda neat - the closest English translation of a general Quine program I know is "print this string, the second time in quotes" (try it - see what happens!), and this basically does exactly that.
You were asking why changing the numbers to 5 and 11 didn't change that 34 was being printed. That's correct! The string literal s has 34 hard-coded into it, so changing the 5 and 11 in the call to printf won't change that. What it will do is no longer print the quotation marks around the inside of the string s and instead print non-printing characters.

Resources