How to change the content of pointer without changing its pointing address? - c

I am trying to append a string t in a string s using pointers.
#include<stdio.h>
#include "my_functions.h"
int main(void)
{
char* s = "H"; /*First string*/
char* t = "W"; /*String to be appended*/
char* buff; /*used to store the initial value of s pointer*/
buff = s;
while(*s != '\0')
{
s++;
}
/*At the end of the loop I will get a memory add where string s
ends*/
/*Start appending second string at that place*/
char* temp; /*Creating a temporary pointer to store content
value of second string*/
temp = t;
t = s; /*t now points to the new starting position for
appending operation*/
*t = *temp; /*------ERROR-------*/
/*Rest is to just print the whole appended string at
once*/
s = buff;
while(*s!='\0')
{
printf("%c\t",*s);
s++;
}
printf("Works Fine");
return 0;
}
I am not getting any output on the terminal, nor any errors. The Idea is to change the content of new location of t which is '\0' to the content of t to be appended that is 'W'. I am a noob. Any suggestions? Where Am I wrong?

I suggest you to study this code:
char *strcat(char *dest, const char *src)
{
char *ret = dest;
while (*dest)
dest++;
while (*dest++ = *src++)
;
return ret;
}
Obviously the input parameter dest MUST be a pointer that points a memory area at least big as the sum of the two strings length (pointed by dest and src) + 1 byte (the 0 terminator).

Related

write a function for copying two strings

this code is not printing the copied value of two strings given that are target and source been created above then a function is created that is stringcopy .
#include <stdio.h>
int stringcopy(char *target, char *source) {
char *start = target;
while (*target != '\0') { // this means while target is not equal to 0 that is null charecter
*target = *source;
target++;
source++;
}
*target ='\0';
return *start;
}
int main() {
char source[34] = "Harry";
char target[34];
char copy = stringcopy(target, source);
printf("%s", copy);
return 0;
}
*target != '\0' but *target is uninitialized. You mean *source != '\0'.
Next problem: int stringcopy should be char *stringcopy. Your code will appear to work on a 32 bit platform otherwise, but it will blow up x64. You need to return the correct type.
Third problem: char copy = ; should be char *copy = ; I'm guessing you got here by arbitrarily mutating the code to get it to compile due to the second problem.
Forth problem: return *start; should be return start;. Thanks to Gerhardh for catching it.

String copy in C using pointers doesn't show expected result

I was trying to implement a string copy function using pointers as shown below:
#include <stdio.h>
#include <stdlib.h>
void copyStringPtr(char *from, char *to);
int main()
{
char strSource[] = "A string to be copied.";
char strDestination[50];
copyStringPtr(strSource, strDestination); // Doesn't work.
return 0;
}
void copyStringPtr(char *src, char *dst)
{
printf("The destination was\t:\t%s\n", dst);
// for(; *src != '\0'; src++, dst++)
// *dst = *src;
while(*src) // The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
*dst++ = *src++;
*dst = '\0';
printf("The source is\t\t:\t%s\n", src);
printf("The destination is\t:\t%s\n\n", dst);
}
The expected output is :
The destination was :
The source is : A string to be copied.
The destination is : A string to be copied.
But the output I'm getting is :
The destination was :
The source is :
The destination is :
As it can be seen, even the source doesn't seem to have the initialized value. What am I doing wrong here?
One issue is that you're not initializing char strDestination[50];. Thus it doesn't represent a valid string and when you try to print it here:
printf("The destination was\t:\t%s\n", dst);
It is undefined behavior. You can initialize it like this:
char strDestination[50] = {'\0'};
This explicitly sets the first char to '\0', making it a valid string. And the rest of the array is then default-initialized to '\0' anyway.
Also, after the while loop, your src and dst will point to the null terminator at the end of the strings, so when you print them, it prints nothing. Instead, keep a copy of the original pointers and print those instead:
void copyStringPtr(char *src, char *dst)
{
char* srcOriginal = src;
char* dstOriginal = dst;
...
printf("The source is\t\t:\t%s\n", srcOriginal);
printf("The destination is\t:\t%s\n\n", dstOriginal);
}
Just take a backup of the original pointers before doing the increment. The reason you lose those pointers is, as part of the iteration in the while the start address of the string is lost and the printf() function does not know where the string starts. Since both the original pointers point at \0 at the end of the loop, the printf() function does not see a an actual string to print up-to
You can even make these backup pointers const to disallow modifications made to them.
void copyStringPtr(char *src, char *dst)
{
printf("The destination was\t:\t%s\n", dst);
/*
* backing up the original source/desination
* pointers
*/
const char *b_src = src; const char *b_dst = dst;
while(*src) // The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
*dst++ = *src++;
*dst = '\0';
printf("The source is\t\t:\t%s\n", b_src);
printf("The destination is\t:\t%s\n\n", b_dst);
}
Also as noted in Blaze's answer calling printf() on a uninitialized character array invokes undefined behavior.
I just had to make a minor modification as follows:
#include <stdio.h>
#include <stdlib.h>
void copyStringPtr(char *from, char *to);
int main()
{
char strSource[] = "A string to be copied.";
char strDestination[50];
copyStringPtr(strSource, strDestination); // Doesn't work.
printf("The source is\t\t:\t%s\n", strSource);
printf("The destination is\t:\t%s\n\n", strDestination);
return 0;
}
void copyStringPtr(char *src, char *dst)
{
const char *srcOriginal = src;
const char *dstOriginal = dst;
printf("The destination was\t:\t%s\n", dstOriginal);
// for(; *src != '\0'; src++, dst++)
// *dst = *src;
while(*src) // The null character is equivalent to 0, so when '\0' is reached, the condition equals to 0 or false and loop is exited.
*dst++ = *src++;
*dst = '\0';
}
And it worked just fine. As pointed out by #Jabberwocky in his comment, the pointers *src and *dst in copyStringPtr had moved to the end of the character string and was pointing to the NULL terminator.
#include <stdio.h>
#include <stdlib.h>
void copyStringPtr(char *from, char *to);
int main()
{
char strSource[] = "A string to be copied.";
char strDestination[50] = {0};
copyStringPtr(strSource, strDestination);
return 0;
}
void copyStringPtr(char *src, char *dst)
{
char const *const dstOriginal = dst;
if (!src || !dst){
return;
}
printf("The source is\t\t:\t%s\n", src);
while(src && *src)
*dst++ = *src++;
*dst = '\0';
printf("The destination is\t:\t%s\n\n", dstOriginal );
}

Substrings in the middle of a String in C

I need to extract substrings that are between Strings I know.
I have something like char string = "abcdefg";
I know what I need is between "c" and "f", then my return should be "de".
I know the strncpy() function but do not know how to apply it in the middle of a string.
Thank you.
Here's a full, working example:
#include <stdio.h>
#include <string.h>
int main(void) {
char string[] = "abcdefg";
char from[] = "c";
char to[] = "f";
char *first = strstr(string, from);
if (first == NULL) {
first = &string[0];
} else {
first += strlen(from);
}
char *last = strstr(first, to);
if (last == NULL) {
last = &string[strlen(string)];
}
char *sub = calloc(strlen(string) + 1, sizeof(char));
strncpy(sub, first, last - first);
printf("%s\n", sub);
free(sub);
return 0;
}
You can check it at this ideone.
Now, the explanation:
1.
char string[] = "abcdefg";
char from[] = "c";
char to[] = "f";
Declarations of strings: main string to be checked, beginning delimiter, ending delimiter. Note these are arrays as well, so from and to could be, for example, cd and fg, respectively.
2.
char *first = strstr(string, from);
Find occurence of the beginning delimiter in the main string. Note that it finds the first occurence - if you need to find the last one (for example, if you had the string abcabc, and you wanted a substring from the second a), it might need to be different.
3.
if (first == NULL) {
first = &string[0];
} else {
first += strlen(from);
}
Handle situation, in which the first delimiter doesn't appear in the string. In such a case, we will make a substring from the beginning of the entire string. If it does appear, however, we move the pointer by length of from string, as we need to extract the substring beginning after the first delimiter (correction thanks to #dau_sama).
Depending on your specifications, this may or may not be needed, or another result might be expected.
4.
char *last = strstr(first, to);
Find occurence of the ending delimiter in the main string. Note that it finds the first occurence.
As noted by #dau_sama, it's better to search for ending delimiter from the first, not from beginning of the entire string. This prevents situations, in which to would appear earlier than from.
5.
if (last == NULL) {
last = &string[strlen(string)];
}
Handle situation, in which the second delimiter doesn't appear in the string. In such a case, we will make a substring until end of the string, so we get a pointer to the last character.
Again, depending on your specifications, this may or may not be needed, or another result might be expected.
6.
char *sub = calloc(last - first + 1, sizeof(char));
strncpy(sub, first, last - first);
Allocate sufficient memory and extract substring based on pointers found earlier. We copy last - first (length of the substring) characters beginning from first character.
7.
printf("%s\n", sub);
Here's the result.
I hope it does present the problem with enough details. Depending on your exact specifications, you may need to alter this somehow. For example, if you needed to find all substrings, and not just the first one, you may want to make a loop for finding first and last.
TY guys, worked using the form below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *between_substring(char *str, char from, char to){
while(*str && *str != from)
++str;//skip
if(*str == '\0')
return NULL;
else
++str;
char *ret = malloc(strlen(str)+1);
char *p = ret;
while(*str && *str != to){
*p++ = *str++;//To the end if `to` do not exist
}
*p = 0;
return ret;
}
int main (void){
char source[] = "abcdefg";
char *target;
target = between(source, 'c', 'f');
printf("%s", source);
printf("%s", target);
return 0;
}
Since people seemed to not understand my approach in the comments, here's a quick hacked together stub.
const char* string = "abcdefg";
const char* b = "c";
const char* e = "f";
//look for the first pattern
const char* begin = strstr(string, b);
if(!begin)
return NULL;
//look for the end pattern
const char* end = strstr(begin, e);
if(!end)
return NULL;
end -= strlen(e);
char result[MAXLENGTH];
strncpy(result, begin, end-begin);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *between(const char *str, char from, char to){
while(*str && *str != from)
++str;//skip
if(*str == '\0')
return NULL;
else
++str;
char *ret = malloc(strlen(str)+1);
char *p = ret;
while(*str && *str != to){
*p++ = *str++;//To the end if `to` do not exist
}
*p = 0;
return ret;
}
int main(void){
const char* string = "abcdefg";
char *substr = between(string, 'c', 'f');
if(substr!=NULL){
puts(substr);
free(substr);
}
return 0;
}

function to transfer count number of characters from source string to destination string from right

I have written this function to transfer count number of characters from source string to destination string from right. I am passing string to src, NULL to dst and the count value to function
If i send input string as "Stack overflow" and count as 4 i want the o/p string as "flow". But here my o/p string is always empty, can u pls tell what is wrong in my logic. pls
char *Rprint(const char *src, char *dst, int count)
{
int i = 0;
char *ret = NULL;
while(*src!= '\0')
src++;
dst = malloc(sizeof(char) * (count + 1));
ret = dst;
dst = dst + (count + 1);
while(count)
{
*dst++ = *src--;
count--;
}
*dst++ = '\0';
//return ret;
printf("String:%s \n", ret);
}
I expect you meant to do this:
*dst-- = *src--;
I don't like the way you are doing this, but that should get you on track without me suggesting that you completely rewrite your code.
You should not null-terminate the string afterwards, because you have already copied the terminator. You are copying your string from the end to the beginning (ie reverse-copy), but confusing it with the more usual forward-copy.
Be careful with your loop condition. You might have an off-by-one error there. Same with adding count+1 to dst. I think you should only add count.
Oh, and don't forget to return a value from your function!
Here is the working code , based on your original approach , but with few corrections.
#include <stdio.h>
void Rprint(const char [], char [], int );
int main()
{
char buff[50] = "stack overflow";
char cut [50];
Rprint(buff,cut,5);
puts(cut);
}
void Rprint(const char src[], char dst[], int count)
{
while(*src!= '\0')
src++;
src = src - count;
while(count--)
*(dst++) = *(src++);
*(dst++) = '\0';
}

String reverse using pointers

I'm trying to reverse a string using pointers.When i try to print the reversed string instead of getting DCBA i'm getting out only as BA?Can anyone help me on this?
#include<stdio.h>
void reverse(char *);
void main()
{
char str[5] = "ABCD";
reverse(str);
}
void reverse(char *str)
{
char *rev_str = str;
char temp;
while(*str)
str++;
--str;
while(rev_str < str)
{
temp = *rev_str;
*rev_str = *str;
*str = temp;
rev_str++;
str--;
}
printf("reversed string is %s",str);
}
You're losing your pointer to the beginning of the string, so when you print it out you're not starting from the first character, because str no longer points to the first character. Just put in a placeholder variable to keep a pointer to the beginning of the string.
void reverse(char *str)
{
char *begin = str; /* Keeps a pointer to the beginning of str */
char *rev_str = str;
char temp;
while(*str)
str++;
--str;
while(rev_str < str)
{
temp = *rev_str;
*rev_str = *str;
*str = temp;
rev_str++;
str--;
}
printf("reversed string is %s\n", begin);
}
char* strrev(chr* src)
{
char* dest
int len=0 ; //calculate length of the src string
int index=0 ; // index for dest (output) string
int rindex=0; //Index to be counted from end toward beginning of src string
//Calculate length of the string
//Keep iterating till it reaches to null char '\0'
while(*(src+len) != '\0')
{ len++ }
//pointing rindex at the last character of src string
rindex=len-1;
//Start copying from last char of src string at first index of dest array
// Copying second last char of src string at second index of dest array and so on ..
while(rindex > =0)
{
*(dest+index) = *(src + rindex)
index++;
rindex--;
}
// Finally covert array of char into string , by inserting a null char at the end of dest array
*(dest+index) = '\0';
return dest;
}

Resources