#include <stdio.h>
#include <string.h>
int main()
{
char *str3;
str3="Final string.";
for(;*str3;)
{
printf("%c", *str3++);
}
printf("\n");
printf("%d bytes", strlen(str3));
return 0;
}
I've been confused about why the output says 0 bytes when it should be saying 13 bytes. I removed the for loop like so:
#include <stdio.h>
#include <string.h>
int main()
{
char *str3;
str3="Final string.";
printf("%d bytes", strlen(str3));
return 0;
}
and the output comes out correct saying 13 bytes. So I figured it had something to do with the for loop. My guess was: The loop reads through the contents but updates the variable as it goes along i.e. *str3++, once it's complete there's no data left to read and all the data that was already read is, well, read & gone (hehe)... which means 0 bytes?? Like reading a book and whiting out the last word you read.
If that's the case I'd have to refill it with data, do a repeat initialization by putting str3="Final string."; directly after the for loop and it'll show the correct output...but...I feel like that's a bad/cheap trick?
I'm not exactly sure what's happening. Please help.
Thanks in advance!!
Before for loop, str3 is pointing to:
str3
|
V
+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
|F|i|n|a|l| |s|t|r|i|n|g|.|\0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
In for loop you are incrementing str3 in printf() till str3 hits null-character:
printf("%c", *str3++);
So, after for loop str3 is pointing to:
str3
|
V
+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
|F|i|n|a|l| |s|t|r|i|n|g|.|\0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+--+
strlen() determines the length of a string by terminating null-character. Since str3 is pointing to terminating null-character of string, hence you are getting the output 0.
You can take another pointer and point it to str3 and use it in for loop, like this:
#include <stdio.h>
#include <string.h>
int main()
{
char *str3, *tmp;
str3="Final string.";
tmp=str3;
for(;*tmp;)
{
printf("%c", *tmp++);
}
printf("\n");
printf("%zu bytes", strlen(str3));
return 0;
}
Output:
Final string.
13
Additional:
strlen() return type is size_t. You should use format specifier %zu for printing the strlen returned value.
You are incrementing the str pointer until it points to 0 (the end of the string) and when you call strlen(str3) it returns 0.
you are advancing the pointer to the start (initialization)of the string until it points to the end of the string. Hence when you call strlen on it you get size 0 - at that point it already points to the end of the string
you should use an auxillary pointer to iterate the string - advance it while iterating while the strlen command will be with the original str3
you can also add a counter in your for body and that will save you the need to call strlen at the end
in your case the string is literal and does not need to be freed, but when the strings are dynamically allocated working with an auxillary pointer is a must. - you must free allocated memory with the original pointer (returned from the allocation)
Related
The code is supposed to print out 13:Hello World!, but the output is only 13:.
#include <stdio.h>
int main(){
char *str = "Hello World!\n";
int Laenge= 0;
while (*str++){
++Laenge;
}
printf(" %d:%c\n", Laenge, *str);
return 0;
}
You set str to point to the beginning of the string, and then you increment str till you get to the end. By that time, str is now pointing to the end of your string.
Try using a different pointer to walk through your string, or just save a copy of the pointer for later use.
It also looks like you're syntax is wrong for the print statement. I haven't coded in C for decades. I'm a Python user now. But I think *str would reference one char, and you want to reference the entire string. So if str was not corrupted, use %s and str instead of %c and *str in your printf().
You can interate till you find the null character!
#include <stdio.h>
int main()
{
char *str = "HELLO WORLD!\n";
int len = 0;
while(*(str + len) != '\0'){
len++;
}
printf("%d:%s", len, str);
return 0;
}
Your code is not working because your are incrementing the original string and converting it to '\0'. Use a walker.
you need to remeber the original str pointer
you should printf str not *str
#include <stdio.h>
int main(){
char *str = "Hello World!\n";
char *temp = str;
int Laenge= 0;
while (*temp++){
++Laenge;
}
printf(" %d:%c\n", Laenge, str);
return 0;
}
The code is only supposed to do what it has been programmed to do, to the letter of the law. Unfortunately, what's written doesn't always coincide with what the programmer intended the program to do.
In the while loop, you increment str until you reach the end, at which point the while loop ends. Now the pointer points to the end of the string.
Other than that, the format specifier for a string is %s, not %c. The %c would only print a single character. Change *str to str, unless you want to print a single character, but then you mentioned the expected output is supposed to be Hello, World.
Note:
Do not post text as an image. Post text as text, one can't copy and paste your code from an image. It's difficult to see where the problem may be arising from, and hence is difficult to debug.
So I'm trying to reverse a string, but I get a memory fault. Memory for s and s1 is initialized enough to accomodate the '/0' character as well.
Interestingly if I remove *s=*s1 and print s1 instead the program works.
But I haven't even set the "\0" character at the end of s1 so how does it even know where to stop printing?
And in the case below what exactly is the issue?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main(void)
{
char *s = "abcdefghijklmnop", *s1=malloc(17);
int i;
for(i=0;i<strlen(s);i++)
{
*(s1+i) = *(s+strlen(s)-1-i);
}
*s=*s1;
printf("%s",s);
}
The char *s = "abcdefghijklmnop" is a string literal which is often in read-only memory.
An error will be generated if you attempt to modify a string literal.
You attempt to replace the first character in s with the first character in s1 when you do *s=*s+1.
If s wasn't a string literal, you should've done s=s1 instead of *s=*s1 to make s its reverse.
More about this:
https://softwareengineering.stackexchange.com/questions/294748/why-are-c-string-literals-read-only
String literals: Where do they go?
where in memory are string literals ? stack / heap?
The correct string is printed with printf("%s", s1); even if no \0 was stored because the memory next to the last character just happened to be 0 which is equivalent to \0. This needn't always be so and cannot be relied upon as malloc() doesn't initialise the memory that it allocates.
But calloc() will initialise the memory it allocates to 0.
See more here.
In your code *s=*s1 only copy the first content of s1 into s. i.e, *(s+0)=*(s1+0) not the entire string. So we need to assign the address of s1 to s. i.e, s=s1.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *s = "abcdefghijklmnop", *s1=malloc(17);
int i;
for(i=0;i<strlen(s);i++)
{
*(s1+i) = *(s+strlen(s)-1-i);
}
s=s1;
printf("%s",s);
free(s1);
return 0;
}
It is good practice to free the memory after its use.
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.
Look what I found with this simple code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *string;
int main(){
string = (char *) malloc(50*sizeof(char));
strcpy(string, "initi1l wording cont2ining forty-nine ch3r4cters.");
printf("BEFORE: %s\n", string);
string = (char *) realloc(string, 24*sizeof(char));
printf("AFTER: %s\n", string);
system("PAUSE");
return 0;
}
The outpout is:
BEFORE: initi1l wording cont2ining forty-nine ch3r4cters.
AFTER: initi1l wording cont2inia
Notice it 'a' at the end of the string! I have no idea where this comes from, maybe somewhere in the heap. It is not from the original data block. Initially I was using realloc() with arrays of structures and it was obviously corrupting the data in more significant ways.
How can I work around this problem?
C strings require a NUL terminator. You're implicitly expecting realloc() to somehow figure out that the memory contains a C string, and replace its last character with NUL. It doesn't do this; you have to do it yourself:
string = (char *) realloc(string, 24*sizeof(char));
string[23] = 0; // <========= THE FIX
printf("AFTER: %s\n", string);
In other words, it's a bug in your code.
It does not! In C "String" is a set of character delimited with \0. In this case you try to print "string", therefore you get your original 24 characters and some tail until random \0 is found in memory
Strings in C are null terminated. I am surprised that the program did not crash.
It's character 25 and you have no 0-termination in the first 24.
I have to compare few characters of string say from 2nd char till 4th character( counting starts from zero)
The string is stored in elements of structure say zoopla->real
for example zoopla ->real has '447889036' where real is of type char real[20];
Also please note I cant use function strnstr.
The code works as expected but just for curiousity, I have added printf statement and it shows me value till 4th cahr and then some garabe characters.
I want to know why the printf statment is showing 2 extra garabe values?
char * copyTemp;
char *strptr;
copyTemp = (char *)malloc(sizeof(char)*6);
strncpy(copyTemp, zoopla->real, 5);
printf("the string copied is %s", copyTemp); // debug statemnt
strptr = strstr(copyTemp, "666");
if(strptr != NULL)
{
//some other function
}
else
//some other function
free(copyTemp);
All criticism and suggestions are welcome
It seems to me that copyTemp is not null terminated. That's why printf shows you garbage characters after the characters you put in there. It doesn't know where to stop so it continues iterate through memory.
Add
copyTemp[5] = '\0';
after strncpy.
See this example from the documentation of strncpy:
/* strncpy example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]= "To be or not to be";
char str2[6];
strncpy (str2,str1,5);
str2[5]='\0';
puts (str2);
return 0;
}
see
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.
you have to add null your self.
if you will be allocating memory of constant size then use array only.
#include <stdio.h>
#include <string.h>
int main ()
{
char * copyTemp;
char *strptr;
copyTemp = (char *)calloc(sizeof(char),6);
strncpy(copyTemp, "88666782921", 5);
printf("the string copied is %s", copyTemp); // debug statemnt
strptr = strstr(copyTemp, "666");
if(strptr != NULL)
{
//some other function
}
else
//some other function
free(copyTemp);
return 0;
}
According to my old K&R, strncpy will only implicitly add null bytes if the source string has fewer characters than the number to be copied.
In this case, zoopla->real has more than 5 characters, so the function is simply copying the first five characters. Since you haven't initialized the memory to zero, or explicitly added a null byte, the string is not terminated after the fifth character. So when you print the string, you get additional bytes with essentially random values, until one is hit that happens to be zero.