This question already has answers here:
Strings and character with printf
(7 answers)
Closed 1 year ago.
Pointer are the variables which stores address.
char *ptr = "string";
printf("%s",ptr);
In this code snippet, the whole string was printing without dereferencing. Why was this happening?
And in this case the characters are printing it was working as expected just like an array.
char *ptr = "string";
printf("%c",*ptr);
What is the difference in these two cases
The format string "%s" expects that the corresponding argument points to the first character of a string and the function printf outputs the string until the terminating zero character '\0' is encountered.
In fact this call of printf
char *ptr = "string";
printf("%s",ptr);
is logically implemented under the hood the following way
#include <stdio.h>
int main(void)
{
char *ptr = "string";
for ( char *tmp = ptr; *tmp != '\0'; ++tmp )
{
printf( "%c", *tmp );
}
return 0;
}
The format string "%c" expect an object of the type char and the function printf outputs the object as a character.
The format string (%c or %s) tell it what to treat the parameters as.
The %s is for a string - so walks the pointer printing each character until it hits a \0.
The %c prints one character only.
You are defining a string literal, when you do char *ptr = "string";, which is a null-terminated sequence of characters.
The format argument %s prints a string until \0 is found, while %c prints a single character.
printf("%c", *ptr);
is slightly misleading. To make it clear you want one character out of the string...
printf("%c", ptr[0]);
So for the %c you dereference one char.
The %s dereferences the pointer, increasing it by a char until it reaches a \0.
The %s is equivalent to something like this, using %c:
void printf_s(char *cp) {
while(*cp)
printf("%c", *(cp++));
}
The expression *(cp++) says: cp[0], cp[1],...,cp[n].
Related
#include<stdio.h>
int main()
{
int x=2;
char ch='c';
printf("%i\n",x);
printf("%s\n",ch);
printf("Hello");
return 0;
}
In this code snippet, I accidently put %s for printing the value of ch rather than using %c, but I found that It does not print "Hello". So far, I know, %s accepts a char pointer and it does look for a null character to terminate, but can you explain what is happening here? I am beginner and eager to know about this.
Using an incorrect conversion specifier in printf results in undefined behavior.
You declared the variable ch as having the type char.
char ch='c';
But the conversion specifier %s expects an argument of the type char * that shall point to a (null terminated) string. Thus the value of ch 'c' is interpreted as a memory address.
printf("%s\n",ch);
Instead use
printf("%c\n",ch);
Otherwise declare the variable ch like
char *ch = "c";
and then
printf("%s\n",ch);
I'm new to C and pointers, so i have this problem. I want to tell to pointer how much memory it should point to.
char * pointer;
char arr[] = "Hello";
pointer = arr;
printf("%s \n", pointer);
This pointer will point to whole array, so i will get "Hello" on the screen. My question is how can i make pointer to only get "Hel".
You may try this:
char * pointer;
char arr[] = "Hello";
pointer = arr;
pointer[3] = '\0'; // null terminate of string
printf("%s \n", pointer);
If you always work with strings, then have a look at strlen for getting length of a string. If a string arr has length l, then you may set arr[l/2] = '\0', so that when you print arr, only its first half will be shown.
You may also want to print the last half of your string arr? You can use pointer to point to any place you want as the start. Back to your example, you may try:
char * pointer;
char arr[] = "Hello";
pointer = arr + 2; // point to arr[2]
printf("%s \n", pointer);
Have a check what you will get.
printf has the ability to print less than the full string, using the precision value in the format string. For a fixed number of characters (e.g. 3), it's as simple as
printf( "%.3s\n", pointer );
For a variable number of characters, use an asterisk for the precision, and pass the length before the pointer
int length = 3;
printf( "%.*s\n", length, pointer );
You don't know what a pointer is so I'll explain.
A pointer does not point to a string. It points to a char! Yes, a char. A string in C is really just a set of chars all one after the other in the memory.
A char* pointer points to the beginning of a string. The string ends when there is a '\0' (aka null) char. When you printf("%s",s), what printf does is a cycle like this:
int i;
for(i=0;1;i++) //infinite cycle
{
if(s[i]=='\0')
break;
printf("%c",s[i]);
}
Meaning it will not print a string but all the chars in a char array until it finds a null char or it goes into memory space that is not reserved to it (Segmentation fault).
To print just the 1st 3 characters you could do something like this:
void printString(char* s,int n) //n=number of characters you want to print
{
if(n>strlen(s))
n=strlen(s);
else if(n<0)
return;
char temp=s[n]; //save the character that is in the n'th position of s (counting since 0) so you can restore it later
s[n]='\0'; //put a '\0' where you want the printf to stop printing
printf("%s",s); //print the string until getting to the '\0' that you just put there
s[n]=temp; //restore the character that was there so you don't alter the string
}
Also, your declaration of pointer is unnecessary because it is pointing to the exact same position as arr. You can check this with printf("%p %p\n",arr,pointer);
How much of the string is printed is controlled by the NULL-character "\0", which C automatically appends to every string. If you wish to print out just a portion, either override a character in the string with a "\0", or use the fwrite function or something similar to write just a few bytes to stdout.
You could achieve the objective with a small function, say substring.
#include<stdio.h>
#include<string.h> // for accessing strlen function
void substring(char* c,int len)
{
if (len <= strlen(c)){
*(c+len)='\0';
printf("%s\n",c);
}
else{
printf("Sorry length, %d not allowed\n",len);
}
}
int main(void)
{
char c[]="teststring";
char* ptr=c;
substring(ptr,4); // 4 is where you wish to trim the string.
return 0;
}
Notes:
In C++ a built-in function called substring is already available which shouldn't be confused with this.
When a string is passed to a function like printf using a format specifier %s the function prints all the characters till it reaches a null character or \0. In essence, to trim a string c to 4 characters means you put c[4] to null. Since the count starts from 0, we are actually changing the 5th character though. Hope the example makes it more clear.
int main()
{
int i;
char *names[5] = {"Miri", "Tali", "Ronit", "Avigail", "Shlomit"};
//Printing all the names:
for (i=0; i<5; i++)
printf("%s\n" , names[i]);
return 0;
}
How come its print the whole name? does names[0] (for example) shouldn't print only M?
names is array of character pointers. So names[0] is char * pointing to "Miri".
And similarly for other subsequent items.
In your program names is an array of pointers to char as already was mentioned in Rohan's answer, so to print the first character you should first access the array element and then the the 0th character
printf("%c\n", names[i][0]);
also note that the appropriate specifier is "%c" for one character, since "%s" expects a pointer to char, which should point to a null terminated sequence of bytes, i.e. a string.
Aditionally you should declare the array like
const char *names[5] = {"Miri", "Tali", "Ronit", "Avigail", "Shlomit"};
because the elements are string literals, and should not be modified. So using the const specifier you prevent acidentally doing that.
I am appending a string using single character, but I am not able to get it right. I am not sure where I am making mistake. Thank you for your help in advance. The original application of the method is in getting dynamic input from user.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
int j;
char ipch=' ';
char intext[30]="What is the problem";
char ipstr[30]="";
printf("Input char: ");
j=0;
while(ipch!='\0'){
//ipch = getchar();
ipch = intext[j];
printf("%c", ipch);
strcat(ipstr,&ipch);
j++;
}
puts("\n");
puts(ipstr);
return;
}
Following is the output I am getting.
$ ./a.out
Input char: What is the problem
What is h e
p
oblem
change
strcat(ipstr,&ipch);
to
strncat(ipstr, &ipch, 1);
this will force appending only one byte from ipch. strcat() will continue appending some bytes, since there's no null termination character after the char you are appending. as others said, strcat might find somewhere in memory \0 and then terminate, but if not, it can result in segfault.
from manpage:
char *strncat(char *dest, const char *src, size_t n);
The strncat() function is similar to strcat(), except that
it will use at most n characters from src; and
src does not need to be null-terminated if it contains n or more characters.
strcat requires its second argument to be a pointer to a well-formed string. &ipch does not point to a well-formed string (the character sequence of one it points to lacks a terminal null character).
You could use char ipch[2]=" "; to declare ipch. In this case also use:
strcat(ipstr,ipch); to append the character to ipstr.
ipch[0] = intext[j]; to change the character to append.
What happens when you pass &ipch to strcat in your original program is that the function strcat assumes that the string continues, and reads the next bytes in memory. A segmentation fault can result, but it can also happen that strcat reads a few garbage characters and then accidentally finds a null character.
strcat() is to concatenate strings... so passing just a char pointer is not enough... you have to put that character followed by a '\0' char, and then pass the pointer of that thing. As in
/* you must have enough space in string to concatenate things */
char string[100] = "What is the problem";
char *s = "?"; /* a proper '\0' terminated string */
strcat(string, s);
printf("%s\n", string);
strcat function is used to concatenate two strings. Not a string and a character. Syntax-
char *strcat(char *dest, const char *src);
so you need to pass two strings to strcat function.
In your program
strcat(ipstr,&ipch);
it is not a valid statement. The second argument ipch is a char. you should not do that. It results in Segmentation Fault.
I was confused with usage of %c and %s in the following C program:
#include <stdio.h>
void main()
{
char name[] = "siva";
printf("%s\n", name);
printf("%c\n", *name);
}
Output:
siva
s
Why we need to use pointer to display a character %c, and pointer is not needed for a string
I am getting error when I run
printf("%c\n", name);
I got this error:
str.c: In function ‘main’:
str.c:9:2: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’
If you try this:
#include<stdio.h>
void main()
{
char name[]="siva";
printf("name = %p\n", name);
printf("&name[0] = %p\n", &name[0]);
printf("name printed as %%s is %s\n",name);
printf("*name = %c\n",*name);
printf("name[0] = %c\n", name[0]);
}
Output is:
name = 0xbff5391b
&name[0] = 0xbff5391b
name printed as %s is siva
*name = s
name[0] = s
So 'name' is actually a pointer to the array of characters in memory. If you try reading the first four bytes at 0xbff5391b, you will see 's', 'i', 'v' and 'a'
Location Data
========= ======
0xbff5391b 0x73 's' ---> name[0]
0xbff5391c 0x69 'i' ---> name[1]
0xbff5391d 0x76 'v' ---> name[2]
0xbff5391e 0x61 'a' ---> name[3]
0xbff5391f 0x00 '\0' ---> This is the NULL termination of the string
To print a character you need to pass the value of the character to printf. The value can be referenced as name[0] or *name (since for an array name = &name[0]).
To print a string you need to pass a pointer to the string to printf (in this case name or &name[0]).
%c
is designed for a single character a char, so it print only one element.Passing the char array as a pointer you are passing the address of the first element of the array(that is a single char) and then will be printed :
s
printf("%c\n",*name++);
will print
i
and so on ...
Pointer is not needed for the %s because it can work directly with String of characters.
You're confusing the dereference operator * with pointer type annotation *.
Basically, in C * means different things in different places:
In a type, * means a pointer. int is an integer type, int* is a pointer to integer type
As a prefix operator, * means 'dereference'. name is a pointer, *name is the result of dereferencing it (i.e. getting the value that the pointer points to)
Of course, as an infix operator, * means 'multiply'.
The name of an array is the address of its first element, so name is a pointer to memory containing the string "siva".
Also you don't need a pointer to display a character; you are just electing to use it directly from the array in this case. You could do this instead:
char c = *name;
printf("%c\n", c);
If you want to display a single character then you can also use name[0] instead of using pointer.
It will serve your purpose but if you want to display full string using %c, you can try this:
#include<stdio.h>
void main()
{
char name[]="siva";
int i;
for(i=0;i<4;i++)
{
printf("%c",*(name+i));
}
}
The thing is that the printf function needs a pointer as parameter. However a char is a variable that you have directly acces. A string is a pointer on the first char of the string, so you don't have to add the * because * is the identifier for the pointer of a variable.
Or you can use %c like in the below code:
#include <stdio.h>
void main()
{
char name[]="siva";
//prints as string form
printf("%s\n",name);
//print each letter on different line
int size= sizeof(name);
int i;
for(i=0;i<size;i++){
printf("%c\n",name[i]);
}
}