Why is the answer "abcbcc"? - c

The output of the following program is _________
#include <string.h>
int main()
{
char ch[]="abc",x[3][4];
int i;
for(i=0;i<3;i++)
strcpy(x[i],ch);
for(i=0;i<3;i++)
printf("%s",&x[i][i]);
printf("\n");
}
The answer is abcbcc, but I think the answer should be abc.
strcpy() is used to copy the following to the previous, so the second row of abc is also the third row of abc in the first row array.
a b c
a b c
a b c
Then output diagonal.
Another puzzle: Why is there a & in printf("%s",&x[i][i])?
I thought it would be printf("%s",x[i][i]).

The answer is abcbcc, but I think the answer should be abc.
The answer is correct.
for(i=0;i<3;i++)
printf("%s",&x[i][i]);
printf("\n");
On the first iteration, the value of i is 0.
So the call of printf() is:
printf("%s",&x[0][0]);
which prints abc.
i is then incremented, and the second iteration prints bc, and the third then prints c.
And because you didn't print a newline, the output of all 3 iterations was concatenated.
Why is there a & in printf("%s",&x[i][i])? I thought it would be
printf("%s",x[i][i]).
Because the %s format specifier expects a null-terminated string. And x[i][i] evaluates to a char. Mismatching the types and their format specifiers will lead to undefined behaviour.

Related

Weird result from random character generator in C

I am trying to write a program in C that spits out random characters. Following instructions I found here, I wrote this program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srandom((unsigned) time(NULL));
printf("Tests various aspects of random\n");
char misc;
int num, index;
printf("Enter number of chars: ");
scanf("%d", &num);
printf("\n");
for (int i = 0; i < num; i++) {
index = random() % 26;
misc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[index];
printf("%d:%s\n", index, &misc);
}
}
However, it doesn't behave as I expect. When entering a small number of characters for it to generate, like 10, it makes the expected output.
My expected output is a set of
rand_int:char
pairs printed to the screen.
Here is an example of normal operation
Tests various aspects of random
Enter number of chars:
7:H
4:E
23:X
2:C
4:E
17:R
22:W
11:L
9:J
4:E
However, if I input a large value such as 100, it outputs very strange things like:
Tests various aspects of random
Enter number of chars:
18:Sd
3:Dd
21:Vd
10:Kd
19:Td
19:Td
14:Od
7:Hd
15:Pd
22:Wd
24:Yd
22:Wd
12:Md
[rest omitted for brevity...]
So the question is, why does it behave this way?
What might be a better approach to avoid this?
The comments made by Jabberwocky and Federico klez Culloca got it right.
I was trying to print the character as a string. This was wrong and did weird things.
I needed to use:
printf("%d:%c\n", index, misc);
instead of
printf("%d:%s\n", index, &misc);
All is very simple. The program has undefined behavior. You are using the format string %s that is used to output strings.
printf("%d:%s\n", index, &misc);
However the variable misc is not a character array that contains a string. It is just a single character. So the function printf outputs all characters beyond the variable misc until a zero-terminating character is encountered.
And it seems that the variable num is allocated next to the variable misc. So the printf call outputs also bytes of the variable num that contains the value 100. If to output this value stored in a byte as an ASCII character then you will get the character 'd'.
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
char c = 100;
putchar( c );
putchar( '\n' );
return 0;
}
Its output is
d
Instead of the format %s use the format %c in the printf call. For example
printf("%d:%c\n", index, misc);

problems with c pointer strings

:)
I'm trying to beat string pointers in c, so I write this code but I didn't get the result that I expected.
I'm creating a string variable, and I want to pass it to a function that check if the string lenght is bigger than 10.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool is_bigger_than_10(char *);
int main()
{
char *string1 = "";
int i = 0;
printf("Initial string: %s\n",&string1);
printf("Size is: %d\n",strlen(&string1));
printf("Give me one string: ");
scanf("%[^\t\n]s",&string1); //This scan allows me to enter string with spaces
printf("You write: %s\n", &string1);
printf("Size is: %d\n",strlen(&string1));
printf("String character by character:\n");
for(i = 0; i < strlen(&string1) ; i++)
{
printf("%c ",&string1[i]);
}
printf("\nNow let's check if it's bigger than 10\n");
printf("Answer is: %d",is_bigger_than_10(&string1));
return 0;
}
bool is_bigger_than_10(char *textx)
{
printf("%s --> %d > %d\n",&textx, strlen(&textx),10);
if(strlen(&textx) > 10)
{
return true;
}
else
{
return false;
}
}
The expected output should be:
Initial string:
Size is 0:
Give me one string: axel
You write: axel
String character by character:
a x e l
Now let's check if it's bigger than 10
a x e l --> 4 > 10
Answer is: 0
If yoy run that code and enter axel as the input string you will get this:
Initial string: $0#
Size is 3:
Give me one string: axel
You write: axel
String character by character: a b c d e
a x e l
Now let's check if it's bigger than 10
' --> 3 > 10
Answer is: 0
It's kind of weird, could some one help me to correct this code?
There are two things going on here:
First, your char pointer needs to point somewhere. With the line
char *string1 = "";
you create a pointer to a string literal, which you can't write to. (Obviously you can, given your output, but you just got lucky on a system that allows it.) Create a character buffer instead:
char string1[200] = "";
and ideally enforce the constant buffer limit when you read the string.
Second, you don't need all these &s. The & is not a magic marker that you have to prepend to all your arguments.
The & takes the address of a variable and passes it as a pointer. You need that when the called function needs to change the variable via the pointer. Printing doesn't need to change anything, so unless you want to print the address of a variable with %p, you shouldn't pass addresses. (In the special case of your program, you can just remove all ampersands with search and replace.)
When scanning, you need to change variables if you convert input to numbers or if you scan a char. The exception is when you scan strings with %sor %[...]: Here, you pass a char buffer (as a pointer to its first elements) and the function then fills that buffer.
The problem with scanf and printf is that the arguments after the format string are variadic, which means they will accept any arguments without type checking. The good thing is that most compilers can tell whether a format string matches the arguments and will issue warnings, it you enable them. Do yourself a favour and do that.
(Warnings will also tell you that you have type mismatches in functions where the type of the argument is known, such as your is_bigger_than_10.)

Code blocks output console has stopped working

Whenever i declare a varible as char and scan it as string "%s" my output console crashes. Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char a[20];
int i;
printf("Enter a name ");
scanf("%s",&a);
for(i=0;i<strlen(a);i++)
{
a[i] = toupper(a[i]);
i++;
printf("%s\n",toupper(a[i]));
}
return 0;
}
The second i++; inside the for loop body may cause the index to point off-by-one then, printf("%s\n",toupper(a[i])); will be out of bound access which invokes undefined behavior.
You can remove the i++ from inside the loop body.
Next, toupper(a[i]) returns an int, which is invalid for %s format specifier, which again invokes UB.
That said,
to prevent buffer overflow from excessive long input, it's best to limit the input length with scanf(),
You don't need to pass the address of an array, just the array name will be sufficient
So, overall, you should write
scanf("%19s",a);
You have two problems in the loop where you use toupper and print.
The first is that you increment the variable i twice in the loop.
The second problem is the printf:
printf("%s\n",toupper(a[i]));
Here you ask printf to print a string, but as argument you give it a single character (actually an int, toupper returns an int). Use the "%c" format specifier to print a single character.
By the way, you don't need to call toupper when printing, as the character should already be in upper-case because of the previous assignment.
Your printing loop is mis-behaving and giving you undefined behavior:
printf("%s\n",toupper(a[i]));
is passing toupper(a[i]) to printf()'s %s format specifier, which requires a char * not a plain char. That triggers undefined behavior.
There's no point in printing each character one by one, instead convert the entire string to upper case, then print it once:
for(i = 0; a[i] != '\0'; ++i)
{
a[i] = (char) toupper((unsigned char) a[i]);
}
printf("%s\n", a);
The casts around toupper() are sometimes needed since it takes and returns int, and you want to be a bit careful about when converting to/from characters.
Notice that I factored out the call to strlen(), this might be a bit "too clever" but it's how I would expect this code to be written. If we're going to loop over the characters, there's no need to compute the length separately.

Unable to understand the output of the program using printf weirdly

I was working with some of the interview questions when I found this code.
#include<stdio.h>
int main()
{
short int a=5;
printf("%d"+1,a); //does not give compiler error
return 0;
}
It prints the following:
d
I am unable to understand how the printf function works here.
Let's look at the first argument to the printf() call.
"%d" + 1
This points to the same thing as ptr does in the following code.
char *ptr = "%d";
ptr = ptr + 1;
So, what does it mean to increment a pointer? Well, we advance the pointer sizeof(*ptr) * 1 bytes forward.
So, in memory we have:
%d\0
^^
||
|This is where ("%d" + 1) points to.
This is where ("%d") points to.
So, your code is more or less functionally equivalent to doing:
short int a = 5;
printf("d", a);
Which will evaluate and then ignore the extra function argument and print d.
One more thing: You're very close to causing undefined behavior in that code. printf("%d", a) is using the wrong format string. The correct format string for a short int is "%hd".
You can find a full table of format strings here.
"%d" + 1 does pointer arithmetic, the compiler sees it as "d", so
printf("%d"+1,a);
becomes:
printf("d", a);
You can see why it outputs d in your compiler.
As #sharth points out in the comment, the extra argument a here is evaluated and discarded.
This is my answer based off #DCoder 's comment. "%d" is a pointer to the first character of the two character array %d. Incrementing this by one gives a pointer to d. The fact that there is a second argument now does not matter as the result of the expression "%d"+1 is simply the character d. If you try adding 0 your output is 5 as expected. If you try adding 2, there is no output as there is only "" is being passed to printf.
In this case printf("%d"+1,a); = printf("d",a).
You are specifying printf to print from +1 position which is "d", so printf will simply print d on screen.

printing string in c using a pointer

I was just printing some characters in C.
I have declared char c and assigned its characters.
then using a for loop i try to print the characters one by one.
I have used pointers, of course.
#include <stdio.h>
#include <string.h>
int main()
{
char c[4] = {"hia"};
int i;
for(i=0;i<4;i++)
{
printf(&c[i]);
}
return 0;
}
However when I compile my code using turbo, i get output "hiaiaa" instead of "hia"! What am i doing wrong here?
Your printf() call is broken. You are using the string (from the point you specify) as the formatting string. This will not print single characters. Instead each call will print from where its formatting string starts, to end of the string.
This means the first call will print all of c, the next will print from c[1] and onwards, and so on. Not at all what you wanted.
If you want to print single characters, use the %c format specifier:
printf("%c", c[i]);
No pointer necessary, since the character is passed by value to printf().
This is what happened in your loop:
0. hia
1. ia
2. a
3. \0
However, you want to print exactly one char at a time, not a null terminated string, so you should pass it as char not a char*:
printf( "%c", c[i] )
Also, you are looping four times, but string length is just three. You should use:
for( i = 0; i < strlen( c ); i++ )
...
The printf function have an char* as first argument, that's correct. However, it prints a string (that is, a zero-terminated sequence of char) so it will always do that.
If you want to print one character at a time, then you have to use that format, like in:
printf("%c\n", c[i]);
You also have another problem, and that is that you try to print the zero terminator as well. This character is not printable so will not show. Use e.g. i < strlen(c) as the loop condition to overcome this.
Also, instead of printing character-by-character, print it all as one string:
printf("%s\n", c);
1) For loop size should i<3 , not i<4 (i=3 refers to the null character at the end of the string)
2) use printf("%c",c[i]);
Explanation of what you're seeing: In each loop, printf is printing a null-terminated string. This string starts in every loop one char later inside your array.
How it should be done, depends on what you're intending. If you want to print the string char by char via pointer you may use:
char *p=&c[0];
while (*p) {
printf("%c", *p);
p++;
}
Your question is to print string using pointer. You could use
printf("%s", c);
or character by character as (include library string.h for this)
for(i=0;i<strlen(c);i++)
{
printf("%c", c[i]);
}
in C strings are stored as character arrays and are terminated by a zero-value, so called zero-terminated strings. Btw, this is why you have to make the array size of 4 for thee real chars.
In your example, you are passing pointers th each char to the printf function and printf prints the strings from your pointer to the next null-value . The 1st pass prints "hia", the 2nd ia and the 3rd a.
To print a single char in each pass, you have to use
printf ("%c", c[i]);
Your loop will call printf with the following parameter:
printf("hia"); // first loop iteration
printf("ia"); // second loop iteration
printf("a"); // third loop iteration
printf(""); // fourth loop iteration
You probably meant to print one character at a time:
for(i=0;i<3;i++) // No need to print the string termination character.
{
printf("%c", c[i]); // "%c" is the printf format code to print a single character
}

Resources