Adding an integer to C-String while printing - c

int main(){
printf("hello world"+2);
}
test.c:32:25: warning: adding 'int' to a string does not append to the string
[-Wstring-plus-int]
printf("hello world"+2);
~~~~~~~~~~~~~^~
test.c:32:25: note: use array indexing to silence this warning
printf("hello world"+2);
^
& [ ]
1 warning generated.
alpha#Desktop % ./a.out
llo world%
So this is what I am getting. And if I increase the number then it is simply slicing the string by that.Can anyone explain this output and why it's happening to me?

In the C and C++ languages, every string that has been defined with double quotes is of type char* (pointer to char) as a statically allocated char array. When you call printf() on such string it does something like this:
void printf(char* str) {
while(*str!= '\0') {
// write the current character to stdout
write(STDOUT_FILENO, str, sizeof(char));
str ++;
}
}
I don't know if it really is written that way, indeed it probably isn't, the functionality is the same. It iterates over the string until it finds the null-terminator ('\0'). All pointers are almost equivalent to long and when you add a number to them, it increments their underlying value with sizeof(type), where type is the type of value the pointer points towards. Thus, when you add a number to "Hello World", makes printf() think your string starts on a different memory address and prints 'llo World'.
If you want to print the string with the value '2' appended to the end of it, as #Elliott Frisch stated, you would use print("Hello World%d", 2).
I would suggest looking at sprintf() and strcat() for string concatenation in C.

In C, what we might think of as a string is actually an array of characters. What you pass to printf() in both cases is a pointer to the start of such an array. You can do arithmetic with pointers, which is what you are doing here.
Here's some clarification.
#include <stdio.h>
int main(void) {
// A
printf("Hello, world!\n");
// B
printf("Hello, world!\n" + 2);
}
Output:
Hello, world!
llo, world!
In case A, you point to the start of an array containing the H character, and it reads until the last one (which is in fact a 'this is the end'-character: \0).
⬇️
H
e
l
l
o
,
w
o
r
l
d
!
\n
\0
In case B, you add 2 to the pointer before passing it to printf(). Now printf() starts reading here:
⬇️
H
e
l
l
o
,
w
o
r
l
d
!
\n
\0
This is what causes your 'slice'.

Related

C printf prints an array that I didn't ask for

I have recently started learning C and I got into this problem where printf() prints an array I didn't ask for.
I was expecting an error since I used %s format in char array without the '\0', but below is what I got.
char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };
printf("%c", testArray1[0]);
printf("%c", testArray1[1]);
printf("%c\n", testArray1[2]);
printf("%s\n", testArray1);
the result is
abc
abcqwer
thanks
The format "%s" expects that the corresponding argument points to a string: sequence of characters terminated by the zero character '\0'.
printf("%s\n", testArray1);
As the array testArray1 does not contain a string then the call above has undefined behavior.
Instead you could write
printf("%.*s\n", 3,testArray1);
or
printf("%.3s\n", testArray1);
specifying exactly how many elements of the array you are going to output.
Pay attention to that in C instead of these declarations
char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };
you may write
char testArray1[3] = { "abc" };
char testArray2[] = { "qwer" };
or that is the same
char testArray1[3] = "abc";
char testArray2[] = "qwer";
In C++ the first declaration will be invalid.
%s indeed stop when encountered \0, but testArray1 didn't have that \0, so it keeps printing the following bytes in the memory.
And the compiler magically(actually intentionally) places the testArray2 next to testArray1, the memory is like:
a b c q w e r \0
^ testArray1 starts here
^ testArray2 starts here
And the %s will print all of those chars above until it meets a \0.
You can validate that by:
printf("%d\n", testArray2 == testArray1 + 3);
// prints `1`(true)
As your question, there was no error because the a ... r \0 sequece in memory is owned by your process. Only the program is trying to access an address not owned by it, the OS will throw an error.
Add zero at the end of first array:
char testArray1[] = { 'a','b','c', 0 };
Otherwise printf continues with memory after 'c' until zero byte and there is the second array.
PS: zero 0 is 100% identical to longer ASCII '\0'.

C pointer to character array

I would like to pass a character pointer ( to an array) to a function which will print the letters one by one. For example I am using the code below:
#include<stdio.h>
#include<string.h>
void string1(char *q)
{
while(*q)
{
printf(q++);
printf("\n");
}
}
main()
{
char name[]= "hello";
char *p=name;
string1(p);
}
which prints:
hello
ello
llo
lo
o
But I want it to print;
h
e
l
l
o
I am unable to do it by using the variable q inside printf. Thanks
Your sentence: printf(q++); is wrong.
You have to print a character, only:
printf("%c", *g++);
A better option:
putchar(*g++);
In general, take in account that:
g is the adress of an array of characters.
To access the first character pointed by g, it is necessary to use the operator *, this way: *g.
The modifier "%c" in printf() gives you the possibility of printing a datum of type char.
You should always use a format string with printf. Passing strings with unknown values into the printf function can result in an uncontrolled format string vulnerability. Printing a c-string with printf should be done like this: printf("%s", string_pointer);
That said, to print one character at a time you can use the %c formatter:
while(*q) {
printf("%c\n", *(q++));
}
You need to specify the first argument of printf()
By doing this:
printf(q++);
The application is behaving as if you want to print a string (because it keeps printing until it reaches \0), so what you are doing is equivalent to this;
printf("%s",q++);
But what you actually want is printing only the char at position q:
printf("%c",q++); // Prints only the char at q, then increment q

couldn't able to access the first subscript of an array when %s is used but possible with %c

#include <stdio.h>
#include <string.h>
void main()
{
char array[]="hello";
printf("%s",array[0]);
printf("%c",array[0]);
}
couldn't able to access array[0] when %s is used but able to access array[0] when %c is used, help me to find a solution for this.
you should use address while using with %s ==> &array[0]
because %s requires a pointer as argument.
usually we use
printf("%s",character_array_name);
here character_array_name is the address of first element
character_array_name == &character_array_name[0];
and if you want to print only one character , you need to use
printf("%.1s",character_array_name);
Example Code:
#include<stdio.h>
int main()
{
char *str="Hello World";
printf("%s\n",str); //this prints entire string and will not modify the pointer location but prints till the occurence of Null.
printf("%.1s\n",str); //only one character will be printed
printf("%.2s\n",str); //only two characters will be printed
//initially str points to H in the "Hello World" string, now if you increment str location
str++; //try this str=str+3;
printf("%.1s\n",str); //only one character
printf("%.2s\n",str); //only two characters will be printed
str=str+5; //prints from the W
printf("%s\n",str); //this prints upto Hello because scanf treats space or null as end of strings
printf("%.1s\n",str); //only one character
printf("%.2s\n",str); //only two characters will be printed
return 0;
}
Although you have accepted an answer , I thought my answer could help you in a certain way.
String literals are a sequence of characters and you can visualize your array like this :
+---+---+---+---+---+----+
array: | h | e | l | l | o | \0 |
+---+---+---+---+---+---+-
^
|
array[0]
printf is a variadic function and it doesn't know anything about its arguments until you specify them , so when it sees %c format specifier it assumes that the next argument will be a variable storing a character ,in this case its array[0] that is the character h is stored at the index 0 of the array .
Now, when printf sees a %s it assumes that the next argument will be a pointer pointing the string literal ("hello") that you want it to print , in this case array[0] is not a pointer, you should put array instead in the printf , please note that array names are not pointers but array name decays to pointer
Besides , you should use int main(void) in place of void main its standard

printing int array as string

I am trying to print int array with %s. But it is not working. Any ideas why?
#include<stdio.h>
main() {
int a[8];
a[0]='a';
a[1]='r';
a[2]='i';
a[3]='g';
a[4]='a';
a[5]='t';
a[6]='o';
a[7] = '\0';
printf("%s", a);
}
It prints just a.
I tried with short as well, but it also does not work.
This is because you are trying to print a int array, where each element has a size of 4 byte (4 chars, on 32bit machines at least). printf() interprets it as char array so the first element looks like:
'a' \0 \0 \0
to printf(). As printf() stops at the first \0 it finds, it only prints the 'a'.
Use a char array instead.
Think about the way integers are represented - use a debugger if you must. Looking at the memory you will see plenty of 0 bytes, and %s stops when it reaches a 0 byte.
It prints just a.
That's why it prints just a. Afterwards it encounters a 0 byte and it stops.
Because you declared a as an integer, so those signle characters you initialized would result in an error. You must change it to a char variable. However to save time, just make the variable a pointer using the asterisk character, which then allows you to make a single string using double quotes.
int a[8] means array of 8 ints or 8*(4 bytes) - Say 32 bit architecture
a[0] = 'a' stores in the first int index as 'a''\0''\0''\0'
a[1] = 'r' as 'r''\0''\0''\0' and so on . . .
%s represents any C-style string ie. any string followed by a '\0' character
So
printf("%s", a);
searches for trailing '\0' character and just prints "a" assuming it is the entire string

C, pointer, string

main()
{
char *x="girl";
int n,i;
n=strlen(x);
*x=x[n];
for(i=0;i<n;i++)
{
printf("%s \n",x);
x++;
}
}
What is the output?
Please explain the output.......................
o/p is :
irl
rl
l
The output is undefined behaviour. You modified a string literal.
As others have pointed out, the program as written has undefined behaviour.
If you make a small alteration:
char x[] = "girl";
then I believe it is legal, and possible to explain. (EDIT: Actually there are still problems with it. It's int main(), and you should return 0; at the end. You also need to #include <string.h> because you are using strlen, and #include <stdio.h> because you are using printf.)
The line
*x = x[n];
sets x[0] (i.e. *x) to x[4] (which happens to be the string terminator '\0'). Thus the first string to be printed is the empty string, because the very first character is the string terminator.
We then loop through the string, one character at a time, printing the substrings:
irl
rl
l
While the result is undefined behavior, as DeadMG said, let's assume you declared x as char x[] = "girl".
You assign 4 to n (since the length of the word "girl" is 4), and you assign the value in x[4] to *x (which is x[0]), but this value is '\0' (null terminator)
Now you loop and print the word from x to the next null terminator, but the first time, the first char is the null terminator, so you get nothing. after that you print the word from incrementing index.
g i r l \0
*x = x[4]:
\0 i r l \0
^ ^ ^ ^
it1 it2 it3 it4 // << Where does x points to in each iteration of the for loop
The code is distictly suspect. *x=x[n] attempts to overwrite the literal "girl", and the effect will vary between platforms and compilers. More correctly it should be declared as:
const char *x = "girl";
and then it will not (should not) compile.

Resources