I am studying pointers right now. So, arrays are simultaneously studied with that. It says that address of first of element of array arr is &arr[0] which can also be written as arr.
But as i know that string is an array of characters so if have a string:
char string[] = "ilovejapan";
and then print it using printf
printf("%s", string);
shouldn't it be just printing the first address? Really confused Now.
Question updated: Now in the example below *W points to word that means it pointers to the first address of the string word right? How does this access complete string word?
int getword(char *word, int lim)
{
int c, getch(void);
void ungetch(int);
char *W = word;
while (isspace(c = getch()))
;
if (c != EOF)
*W++ = c;
if (lisalpha(c)) {
*W = '\0';
return c;
}
for ( ; --lim > 0; W++)
if ( lisalnum(*W = getch())) {
ungetch ( *W) ;
break;
}
*W = '\0';
return word[O];
}
The conversion specifier %s says, "Give me the address of a character. I will print that character, and then look at the next higher address and print that character, and so forth, until the character at the address I'm looking at is zero". So string is indeed the address of a character, but printf knows what to do with it.
char string[0] = "ilovejapan"; isn't a valid declaration. Maybe you meant to leave the 0 out?
Anyway, the %s format specifier is intended to match up with a pointer to a string, which in your case is just fine. It prints characters from that address up until the terminating null character.
When you pass string in printf("%s", string);, you are telling printf you want to print a string and you are telling the function the address of the first character in the string. Using its address, printf can figure out what character is stored at that address, and increments the address of the first character to get the address of the second character, and prints that character, and so on. It stops printing when it finds a character (not that character's address, but the actual character itself) whose value is '\0' (the "zero" character, or the character represented by the number 0). If that makes any sense.
Related
This is a program in C to print a string in reverse using a pointer.
What is the meanning of *pre='\0'?
#include <stdio.h>
int main()
{
char string[50],reserve[50];
char *ps = string;
char *pre = reserve;
int i=-1;
printf(" Input a string : ");
scanf("%s",string);
while(*ps)
{
ps++;
i++;
}
while(i>=0)
{
ps--;
*pre = *ps;
pre++;
--i;
}
*pre='\0';
printf(" Reverse of the string is : %s\n\n",reserve);
return 0;
}
Setting *pre='\0'; is an idiomatic way of adding a NUL-terminator to the end of your char[] array. This is required for the C string type functions to work: e.g. the printf call with %s specifier.
You are using %s in printf and it expects its argument to be null terminated. It is not necessary to null terminate if you are treating reverse as a character array and then you can use a loop and print the reversed string character by character.
*pre='\0';
Here backward slash is for escape sequence and 0 is representing the null character'\0'. In C language we use null character to end the string. So suppose you ask user to enter string.
scanf("%s",s);
Here user enter stackoverflow so total 13 characters. But to store that string actually we need an array size of 14. Because we have have to add null character at the end of string.
Here, in our String data will store something like this...
s[]={'s','t','a','c','k','o','v','e','r','f','l','o','w','\0'};
So Question is why do we need to end a string with null character? Answer is simple, so we could know that where string is ending.
while(*ps){
ps++;
i++;
}
while(i>=0){
ps--;
*pre = *ps;
pre++;
--i;
}
*pre='\0';
Here in first while loop *ps and i will increment until *ps!='\0'. And in second while loop run until i >= 0 is true. *ps decrement and assign *ps data to *pre so string can be reversed. And when second while loop ends *pre='\0' you are ending the reverse string with null character.
long story in short :)
when you enter string through scanf("%s",s); compiler will end add the null character at the end of string. But when you manipulate (reversing) the string you have to end reverse string with null character at the end. and that's what you have done by *pre='\0'; this line.
To make more sense about it you should make basic string program and read about string.
I am learning C and a I came across this function in my study materials. The function accepts a string pointer and a character and counts the number of characters that are in the string. For example for a string this is a string and a ch = 'i' the function would return 3 for 3 occurrences of the letter i.
The part I found confusing is in the while loop. I would have expected that to read something like while(buffer[j] != '\0') where the program would cycle through each element j until it reads a null value. I don't get how the while loop works using buffer in the while loop, and how the program is incremented character by character using buffer++ until the null value is reached. I tried to use debug, but it doesn't work for some reason. Thanks in advance.
int charcount(char *buffer, char ch)
{
int ccount = 0;
while(*buffer != '\0')
{
if(*buffer == ch)
ccount++;
buffer++;
}
return ccount;
}
buffer is a pointer to a set of chars, a string, or a memory buffer holding char data.
*buffer will dereference the value at buffer, as a char. This can be compared with the null character.
When you add to buffer - you are adding to the address, not the value it points to, buffer++ adds 1 to the address, pointing to the next char. This means that now *buffer results in the next character.
In the loop you are incrementing the pointer buffer until it points to the null character, at which point you know you scanned the whole string. Instead of buffer[j], which is equivalent to *(buffer+j), we are incrementing the pointer itself.
When you say buffer++ you increment the address stored in buffer by one.
Once you internalize how pointers work, this code is cleaner than the code that uses a separate index to scan the character string.
In C and C++, arrays are stored in sequence, and an array is stored according to its first address and length.
Therefore *buffer is actually the address of the first byte, and is synonymous with buffer[0]. Because of this, you can use buffer as an array, like this:
int charcount(char *buffer, char ch)
{
int ccount = 0;
int charno = 0;
while(buffer[charno] != '\0')
{
if(buffer[charno] == ch)
ccount++;
charno++;
}
return ccount;
}
Note that this works because strings are null terminated - if you don't have a null termination in the character array pointed to by *buffer it will continue reading forever; you lose the bit where c knows how long the array is. This is why you see so many c functions to which you pass a pointer and a length - the pointer tells it the [0] position of the array, and the size you specify tells it how far to keep reading.
Hope this helps.
In the following code, fizz prints correctly, but buzz does not. What is wrong with using a char array here or in what way am I using it wrong?
#include <stdio.h>
int main() {
int i;
char *fizz = "fizz";
char buzz[4] = "buzz";
for(i = 1; i <= 100; i++) {
if(!((i %3 == 0) || (i%5 == 0)))
printf("%d", i);
if(i%3 == 0)
printf("%s", fizz);
if(i%5 == 0)
printf("%s", buzz);
printf("\n");
}
}
Neither string is actually four bytes long. C strings are NUL-terminated, so they're always their length in characters plus one for the '\0' character. Therefore, you should change the declaration of buzz as follows:
char buzz[5] = "buzz";
However, also note that explicitly declaring the variable's length when initializing with a string literal is not required. You can just leave out the number, and it will work fine.
char buzz[] = "buzz";
The %s specifier prints a string. A string is a series of characters followed by a null-terminator. To put it another way, you tell printf where your characters start, and printf keeps printing until it encounters a null terminator.
The "buzz" expression is a null-terminated string, however you shoe-horned it into char buzz[4] so the null terminator didn't fit. The result is that the buzz array does not contain a null terminator, and so printf reads off the end of the string, causing undefined behaviour. To fix this write:
char buzz[] = "buzz";
which will include a null terminator and allocate the right amount of space.
You have declared the size of the buzz array as 4 and including \0 the size of the string is 5. so you have to change the size of the buzz array as 5 or don't mention the size.
char buzz[5] = "buzz";
because buzz is not a pointer variable, if the buzz is a pointer variable it will allocate the memory according to the string, so there is no need to specify the size.
As buzz is a array you have to mention the size correctly.
And while printing we use %s , %s will print the string till the \0 character occurs.
In the buzz string there is no \0 character, this is the problem.
buzz contains 4 character, it has no space reserved for the null character, therefore it cannot be printed correctly with %s. %s specifies that a null terminated string to be printed and it cannot work correctly if the string is not null terminated.
Change your initialization to char buzz[] = "buzz"
Why do we need to add a '\0' (null) at the end of a character array in C?
I've read it in K&R 2 (1.9 Character Array). The code in the book to find the longest string is as follows :
#include <stdio.h>
#define MAXLINE 1000
int readline(char line[], int maxline);
void copy(char to[], char from[]);
main() {
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = readline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0)
printf("%s", longest);
return 0;
}
int readline(char s[],int lim) {
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0'; //WHY DO WE DO THIS???
return i;
}
void copy(char to[], char from[]) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
My Question is why do we set the last element of the character array as '\0'?
The program works fine without it...
Please help me...
You need to end C strings with '\0' since this is how the library knows where the string ends (and, in your case, this is what the copy() function expects).
The program works fine without it...
Without it, your program has undefined behaviour. If the program happens to do what you expect it to do, you are just lucky (or, rather, unlucky since in the real world the undefined behaviour will choose to manifest itself in the most inconvenient circumstances).
In c "string" means a null terminated array of characters. Compare this with a pascal string which means at most 255 charactes preceeded by a byte indicating the length of the string (but requiring no termination).
Each appraoch has it's pros and cons.
Especially string pointers pointed to array of characters without length known is the only way NULL terminator will determine the length of the string.
Awesome discussion about NULL termination at link
Because C defines a string as contiguous sequence of characters terminated by and including the first null character.
Basically the authors of C had the choice to define a string as a sequence of characters + the length of string or to use a magic marker to delimit the end of the string.
For more information on the subject I suggest to read this article:
"The Most Expensive One-byte Mistake" by Poul-Henning Kamp
http://queue.acm.org/detail.cfm?id=2010365
You have actually written the answer yourself right here:
void copy(char to[], char from[]) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
The loop in this function will continue until it encounters a '\0' in the array from. Without a terminating zero the loop will continure an unknown number of steps, until it encounters a zero or an invalid memory region.
Really, you do not need to end a character array by \0. It is the char*, or the C representation of the string that needs to be ended by it.
As for array, you have to add a \0 after its end if you want to transfer it to the string (representer by char*).
On the other hand, you need to have \0 at the end of the array, if you want to address it as char* and plan to use char* functions on it.
'\0' in the array indicates the end of string, which means any character after this character is not considered part of the string.It doesn’t mean they are not part of the character array. i.e., we can still access these characters by indexing but they are just not part when we invoke string related things to this character array.
For a string to be in proper format and be able to work properly with the string functions, it must be a null-terminated character array. Without NULL, the programs show undefined behavior when we invoke string functions on the character array. Even though we might get lucky with the results most of the times, it still is an undefined behavior.
I've just looked it up
If your array is considered as string
Which means like this char array[MAX]="string";
Or like this scanf("%s",array);
Or char* table;
Then the NULL character '\0' will append automatically as the end of the characters on that table
But if you initialized it like this char array[MAX]={'n','o','t','s','t,'r'};
Or you fill it using character by character with %c format
for(int i=0;i<MAX;i++)
scanf("%c",&array[i]);
Or getchar() instead of scanf("%c",...)
Then you have to add '\0' by yourself
Because now it considered as any other array's type (int,float...) So the cases that we consider as empty are actually filled by random numbers or characters depends on the type
Meanwhile in the case of a string type the next character after the last considered character is by default '\0'
for more explanation the length of this char array[]="12345" is 6
The array[5]=='\0' will return 1
by other words you can't define a string array like this char array[3]="123" because we left no room for the '\0' that has to append automatically
last example char array[7]={'t','e','s','t','\0'};
Here array[4] is the NULL character
array[5] and array[6] are random values
But if it was string then "test" array[4] and 5 and 6 are all filled by the NULL character (NULL character can refers to any white_space as I think so tab '\t' and enter '\n' are also NULL characters just like '\0' which may refer to spacebar)
nota ben: we can't assign array[7] or more as we all know but if you try to output it, it'll show a random value as any empty case
It is string terminating symbol,When this is encountered ,compiler comes to know that your string is ended.
I have a string I composed using memcpy() that (when expanded) looks like this:
char* str = "AAAA\x00\x00\x00...\x11\x11\x11\x11\x00\x00...";
I would like to print every character in the string, and if the character is null, print out "(null)" as a substitute for '\0'.
If I use a function like puts() or printf() it will just end at the first null and print out
AAAA
So how can I get it to print out the actual word "(null)" without it interpreting it as the end of the string?
You have to do that mapping yourself. If you want to, that is. In C, strings are null-terminated. So, if you use a formatted output function such as printf or puts and ask it to print a string (via the format specifier %s) it'd stop printing str as soon as it hits the first null. There is no null word in C. If you know exactly how many characters you have in str you might as well loop over them and print the characters out individually, substituting the 0 by your chosen mnemonic.
The draft says 7.21.6.1/8:
p The argument shall be a pointer to void. The value of the pointer is
converted to a sequence of printing characters, in an
implementation-defined manner.
However, the following:
$ cat null.c
#include <stdio.h>
int main() {
printf("%p\n", (void *)0);
}
produces:
00000000
on both gcc 4.6 and clang 3.2.
However, on digging deeper:
$ cat null.c
#include <stdio.h>
int main() {
printf("%s\n", (void *)0);
}
does indeed produce the desired output:
(null)
on both gcc and clang.
Note that the standard does not mandate this:
s If no l length modifier is present, the argument shall be a pointer
to the initial element of an array of character type.280) Characters
from the array are written up to (but not including) the terminating
null character. If the precision is specified, no more than that many
bytes are written. If the precision is not specified or is greater
than the size of the array, the array shall contain a null character.
Relying on this behavior may lead to surprises!
Instead of printing the string with %s , you will have to come up with a for loop that checks a condition whther a given char in your char array is a \0 and then print the NULL
From C++ Reference on puts() (emphasis mine):
Writes the C string pointed by str to stdout and appends a newline
character ('\n'). The function begins copying from the address
specified (str) until it reaches the terminating null character
('\0'). This final null-character is not copied to stdout.
To process data such as you have, you'll need to know the length. From there, you can simply loop across the characters:
/* ugly example */
char* str = "AAAA\x00\x00\x00...\x11\x11\x11\x11\x00\x00...";
int len = ...; /* get the len somehow or know ahead of time */
for(int i = 0; i < len; ++i) {
if('\0' == str[i]) {
printf(" (null) ");
} else {
printf(" %c ", str[i]);
}
}
One of the key cornerstones of C is strings are terminated by '\0'. Everyone lives by that rule. so I suggest you not think of your string as a string but as an array of characters.
If you traverse the array and test for '\0', you can print "(null)" out in place of the character. Here is an example. Please note, your char * str was created either as a char array or on the stack using malloc. This code needs to know the actual buffer size.
char* str = "AAAA\x00\x00\x00...\x11\x11\x11\x11\x00\x00...";
int iStrSz = <str's actual buffer size>
int idx;
for(idx=0; idx<iStrSz; idx++)
{
if('\0' == *(str + idx)
{
sprintf("%s", "(null)");
}
else
{
putchar(*(str + idx));
}
}
printf("%s", "\n");