C: Returning D as output why? - c

#include <stdio.h>
int main(){
char *s="hello world";
printf("%c\n",s);
}
I have written a small code in C. In last statement of this code I'm using %c format-specifier in printf() function and assigning pointer named s in it. It is giving me D as output. Does it is returning garbage value or does my code automatically assigning ASCII value in it or something else?
When I add s+1 it return E and s+2 return F and so on. Can anyone clarify me?

%c prints a char, not a string. Since your variable s is not a char, but rather a pointer to a char, printf interprets the address to your string as a character. You probably want to use one of the snippets:
printf("%c\n", s[0]); // print the first character in your string
printf("%s\n", s); // print the whole string

regarding:
printf("%c\n",s);
results in the compiler output:
*untitled2.c:5:14: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ *[-Wformat=]*
When compiling, always enable the warnings, then fix those warnings. Suggest:
printf("%s\n",s);
so the statement is using the correct 'output format conversion' specifier to output the whole string
--OR--
to output a single character suggest:
printf( "%c\n", s[0] );
to output only the first character h

On considering how you are doing in this code lets just say, yes you are getting garbage values when you are giving s/s+1/s+2... in printf(). That's just because of your format specifier%c(type is char) is being mismatched with s( type is string). The fix is change the latter to type char and your problems will be fixed.
You don't need to worry about where this value is coming from as, at the end of the day it's a garbage value and will be different for different for different people using the code. And there is no possible usage for it as far as I can see.
Try the following code below and your code will work fine:
char *s="hello world";
printf("%c\n",*s);
or
char *s="hello world";
printf("%c\n",s[0]);
These answers are discussed in answers and comments above.But you should also try this,
char s[]="hello world";
printf("%c\n",s[0]);
Because, although pointers are present in C, swift,etc. They are discouraged because they present major issues for memory safety and garbage collection.
Edit: Stackoverflow fam need some upvotes at the current state i can't even comment. (Only if
i am right)

Related

Char pointers and the printf function

I was trying to learn pointers and I wrote the following code to print the value of the pointer:
#include <stdio.h>
int main(void) {
char *p = "abc";
printf("%c",*p);
return 0;
}
The output is:
a
however, if I change the above code to:
#include <stdio.h>
int main(void) {
char *p = "abc";
printf(p);
return 0;
}
I get the output:
abc
I don't understand the following 2 things:
why did printf not require a format specifier in the second case? Is printf(pointer_name) enough to print the value of the pointer?
as per my understanding (which is very little), *p points to a contiguous block of memory that contains abc. I expected both outputs to be the same, i.e.
abc
are the different outputs because of the different ways of printing?
Edit 1
Additionally, the following code produces a runtime error. Why so?
#include <stdio.h>
int main(void) {
char *p = "abc";
printf(*p);
return 0;
}
For your first question, the printf function (and family) takes a string as first argument (i.e. a const char *). That string could contain format codes that the printf function will replace with the corresponding argument. The rest of the text is printed as-is, verbatim. And that's what is happening when you pass p as the first argument.
Do note that using printf this way is highly unrecommended, especially if the string is contains input from a user. If the user adds formatting codes in the string, and you don't provide the correct arguments then you will have undefined behavior. It could even lead to security holes.
For your second question, the variable p points to some memory. The expression *p dereferences the pointer to give you a single character, namely the one that p is actually pointing to, which is p[0].
Think of p like this:
+---+ +-----+-----+-----+------+
| p | ---> | 'a' | 'b' | 'c' | '\0' |
+---+ +-----+-----+-----+------+
The variable p doesn't really point to a "string", it only points to some single location in memory, namely the first character in the string "abc". It's the functions using p that treat that memory as a sequence of characters.
Furthermore, constant string literals are actually stored as (read-only) arrays of the number of character in the string plus one for the string terminator.
Also, to help you understand why *p is the same as p[0] you need to know that for any pointer or array p and valid index i, the expressions p[i] is equal to *(p + i). To get the first character, you have index 0, which means you have p[0] which then should be equal to *(p + 0). Adding zero to anything is a no-op, so *(p + 0) is the same as *(p) which is the same as *p. Therefore p[0] is equal to *p.
Regarding your edit (where you do printf(*p)), since *p returns the value of the first "element" pointed to by p (i.e. p[0]) you are passing a single character as the pointer to the format string. This will lead the compiler to convert it to a pointer which is pointing to whatever address has the value of that single character (it doesn't convert the character to a pointer to the character). This address is not a very valid address (in the ASCII alphabet 'a' has the value 97 which is the address where the program will look for the string to print) and you will have undefined behavior.
p is the format string.
char *p = "abc";
printf(p);
is the same as
print("abc");
Doing this is very bad practice because you don't know what the variable
will contain, and if it contains format specifiers, calling printf may do very bad things.
The reason why the first case (with "%c") only printed the first character
is that %c means a byte and *p means the (first) value which p is pointing at.
%s would print the entire string.
char *p = "abc";
printf(p); /* If p is untrusted, bad things will happen, otherwise the string p is written. */
printf("%c", *p); /* print the first byte in the string p */
printf("%s", p); /* print the string p */
why did printf not require a format specifier in the second case? Is printf(pointer_name) enough to print the value of the pointer?
With your code you told printf to use your string as the format string. Meaning your code turned equivalent to printf("abc").
as per my understanding (which is very little), *p points to a contiguous block of memory that contains abc. I expected both outputs to be the same
If you use %c you get a character printed, if you use %s you get a whole string. But if you tell printf to use the string as the format string, then it will do that too.
char *p = "abc";
printf(*p);
This code crashes because the contents of p, the character 'a' is not a pointer to a format string, it is not even a pointer. That code should not even compile without warnings.
You are misunderstanding, indeed when you do
char *p = "Hello";
p points to the starting address where literal "Hello" is stored. This is how you declare pointers. However, when afterwards, you do
*p
it means dereference p and obtain object where p points. In our above example this would yield 'H'. This should clarify your second question.
In case of printf just try
printf("Hello");
which is also fine; this answers your first question because it is effectively the same what you did when passed just p to printf.
Finally to your edit, indeed
printf(*p);
above line is not correct since printf expects const char * and by using *p you are passing it a char - or in other words 'H' assuming our example. Read more what dereferencing means.
why did printf not require a format specifier in the second case? Is printf(pointer_name) enough to print the value of the pointer?
"abc" is your format specifier. That's why it's printing "abc". If the string had contained %, then things would have behaved strangely, but they didn't.
printf("abc"); // Perfectly fine!
why did printf not require a format specifier in the second case? Is printf(pointer_name) enough to print the value of the pointer?
%c is the character conversion specifier. It instructs printf to only print the first byte. If you want it to print the string, use...
printf ("%s", p);
The %s seems redundant, but it can be useful for printing control characters or if you use width specifiers.
The best way to understand this really is to try and print the string abc%def using printf.
The %c format specifier expects a char type, and will output a single char value.
The first parameter to printf must be a const char* (a char* can convert implicitly to a const char*) and points to the start of a string of characters. It stops printing when it encounters a \0 in that string. If there is not a \0 present in that string then the behaviour of that function is undefined. Because "abc" doesn't contain any format specifiers, you don't pass any additional arguments to printf in that case.

C fscanf formatting

I'm quite new to C and I'm having a bit of trouble with these pieces of code:
char word[STRING_LEN];
while(num_words < ARRAY_SIZE && 1 == fscanf(infile, "%79s", &word))
When I try to compile, I get the warning:
format '%s' expects argument of type char *, but argument 3 has type
char (*)[80].
Now this is remedied by using &word[0]. Now, shouldn't these both point to
the address at the start of the array? What am I missing here.
Cheers!
When you use %s format in fscanf, it is expected that the argument is a char* that can hold the characters being read from the stream. That explains the warning message.
In your case, &word has the same numerical value as &word[0]. However, that is not true all the time. For example, if you have:
char* word = malloc(20);
then, the numerical value&word is not equal to that of&word[0]. The compiler is not taking the responsibility for dealing with such distinctions. It is simply expecting a char* as the argument.

pointer to value in array?

So I need to have a pointer to a value in a const char array. But I can't quite get it to work without errors. Here's the code.
int main (void)
{
const char *alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *ptr = &alp[3];
printf("%s\n", ptr);
return 0;
}
Edit- Sorry for not mentioning the errors. The thing is I get tons of different errors depending on where I put different asterisks and ampersands. There is no one particular error. One of the more frequent ones I get says
"incompatible integer to pointer conversion assigning to 'char *'
from 'const char';"
In the end I just want "ptr" to be equal to a pointer pointing to "D" in the array "alp".
If you only want one character to print, change the %s to %c and dereference the pointer
printf("%c\n", *ptr);
It's true that you had a character pointer but %s tells printf to print from that pointer until it reads a null character. So we switch to %c which will print one character but it expects a value rather than a pointer to a value.
alp is a pointer to constant char.
ptr is a pointer to a non-const char.
If you want that to work out you would need to change ptr to be defined as:
char const * ptr = &alp[3];
The const is saying that you're not going to change it, but then you're trying to copy the reference to a variable without that limitation. Instead, try:
const char *ptr = &alp[3];
But note that as other posters have already suggested, this code will give you a pointer to a string beginning with the D (e.g. DEFGHI...), not just the character D.

pointer of char and int

Hi I have a simple question
char *a="abc";
printf("%s\n",a);
int *b;
b=1;
printf("%d\n",b);
Why the first one works but the second one doesnot work?
I think the first one should be
char *a="abc";
printf("%s\n",*a);
I think a stores the address of "abc". So why it shows abc when i print a? I think I should print *a to get the value of it.
Thanks
Ying
Why the first one works but the second one doesnot work?
Because in the first, you're not asking it to print a character, you're asking it to print a null-terminated array of characters as a string.
The confusion here is that you're thinking of strings as a "native type" in the same way as integers and characters. C doesn't work that way; a string is just a pointer to a bunch of characters ending with a null byte.
If you really want to think of strings as a native type (keeping in mind that they really aren't), think of it this way: the type of a string is char *, not char. So, printf("%s\n", a); works because you're passing a char * to match with a format specifier indicating char *. To get the equivalent problems as with the second example, you'd need to pass a pointer to a string—that is, a char **.
Alternatively, the equivalent of %d is not %s, but %c, which prints a single character. To use it, you do have to pass it a character. printf("%c\n", a) will have the same problem as printf("%d\n", b).
From your comment:
I think a stores the address of "abc". So why it shows abc when i print a? I think I should print *a to get the value of it.
This is where the loose thinking of strings as native objects falls down.
When you write this:
char *a = "abc";
What happens is that the compiler stores a array of four characters—'a', 'b', 'c', and '\0'—somewhere, and a points at the first one, the a. As long as you remember that "abc" is really an array of four separate characters, it makes sense to think of a as a pointer to that thing (at least if you understand how arrays and pointer arithmetic work in C). But if you forget that, if you think a is pointing at a single address that holds a single object "abc", it will confuse you.
Quoting from the GNU printf man page (because the C standard isn't linkable):
d, i
The int argument is converted to signed decimal notation …
c
… the int argument is converted to an unsigned char, and the resulting character is written…
s
… The const char * argument is expected to be a pointer to an array of character type (pointer to a string). Characters from the array are written up to (but not including) a terminating null byte ('\0') …
One last thing:
You may be wondering how printf("%s", a) or strchr(a, 'b') or any other function can print or search the string when there is no such value as "the string".
They're using a convention: they take a pointer to a character, and print or search every character from there up to the first null. For example, you could write a print_string function like this:
void print_string(char *string) {
while (*string) {
printf("%c", *string);
++string;
}
}
Or:
void print_string(char *string) {
for (int i=0; string[i]; ++i) {
printf("%c", string[i]);
}
}
Either way, you're assuming the char * is a pointer to the start of an array of characters, instead of just to a single character, and printing each character in the array until you hit a null character. That's the "null-terminated string" convention that's baked into functions like printf, strstr, etc. throughout the standard library.
Strings aren't really "first-class citizens" in C. In reality, they're just implemented as null-terminated arrays of characters, with some syntactic sugar thrown in to make programmers' lives easier. That means when passing strings around, you'll mostly be doing it via char * variables - that is, pointers to null-terminated arrays of char.
This practice holds for calling printf, too. The %s format is matched with a char * parameter to print the string - just as you've seen. You could use *a, but you'd want to match that with a %c or an integer format to print just the single character pointed to.
Your second example is wrong for a couple of reasons. First, it's not legal to make the assignment b = 1 without an explicit cast in C - you'd need b = (int *)1. Second, you're trying to print out a pointer, but you're using %d as a format string. That's wrong too - you should use %p like this: printf("%p\n", (void *)b);.
What it really looks like you're trying to do in the second example is:
int b = 1;
int *p = &b;
printf("%d\n", *p);
That is, make a pointer to an integer, then dereference it and print it out.
Editorial note: You should get a good beginner C book (search around here and I'm sure you'll find suggestions) and work through it.

segmentation fault in C assign string to char

#include <stdio.h>
#include <stdlib.h>
int main()
{
char a="9jhjhi";
printf("%s",a);
}
Why does this throw a segmentation fault? What happens behind the screens?
You need to use char *a = "...".
printf when passed %s will run through a string looking for a 0/NULL byte. In your case you are not assigning a string literal to a, and in fact your compiler should have thrown a warning that you were trying to initialize a char from a pointer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *a="9jhjhi";
printf("%s",a);
}
Your error is that
char a="9jhjhi";
should be
char *a="9jhjhi";
What happens is undefined behavior - so anything could happen.
Your assigning a string literal to a char, so your a will contain a pointer(to the beginning of that string) converted to a char - whatever that'll be.
%s conversion in printf assumes you pass it a string, which must be a char* pointing to a sequence of chars ending with a 0 terminator. You passed it a char, which certainly does not meet those requirements, so it's quite undefined what'll happen - a crash could be common.
You should also return something from the main() method - it's declared to return an int after all.
a is initialized to a (cast to integer and truncated because char is 3 or 7 bytes too small) pointer that points to a char array (propably somewhere in ROM). What follows is undefined, but it's propably like this: When you pass it to printf with a %s in the format string, it takes the value of a (something in 0-255) and 3 (or 7) unrelated bytes from the stack, gets some bogus address and wreaks havok by accessing someone else's memory.
Use char *a = ....
C does not have strings as in String b = new String();
C has arrays of type char.
So char a="123123" should be a character array.
You aren't using anything from stdlib.h in that code either so there is no reason to #include it.
Edit: yeah, what nos said too. An array name is a pointer.
You mean
char *a = "9jhjhi";
If this compiles without warnings, your compiler settings are messed up. The warnings from gcc show plainly what's happening:
test.c: In function ‘main’:
test.c:5: warning: initialization makes integer from pointer without a cast
test.c:6: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
The string literal is interpreted as a pointer, which is converted (and truncated) to a char.
Then the char is sent into printf as a number, but interpreted as a string. Since it's not null-terminated in any way, printf probably overruns memory when racing through that "string".
When you declare char a without a pointer symbol, you are only allocating enough space on the stack for a single character.
Strings in C are represented by a char array, or a pointer to a char array, terminated by the null character '\0'. But if you use a literal string, the compiler takes care of all of that for you.
Here's how you can get your code to work, then:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *a = "9jhjhi";
printf("%s",a);
}
First of all, you're trying to save an entire string into a single char variable. Use char array (char[size]) instead. You may also want to terminate the string with "\0".
You could remove this error in two ways.
1.char * p="karthik A"
2.char [ ]p="karthik A"

Resources