#include<stdio.h>
char * sstrcat(char*,char*);
void main() {
char *c;
char s[100] = "abcde";
char t[] = "fghi";
c = sstrcat(s,t);
printf("%s",c);
}
char* sstrcat(char *s,char *t) {
char* temp = s;
while(*s++ != '\0');
while((*s++ = *t++) != '\0');
return temp;
}
Above written code I am getting output abcde but expected output is concatenation of string s and t.
Please help me to figure out what mistake I am doing ?
thanks.
This line
while(*s++ != '\0');
will increment s after the comparison has been made, leaving '\0', which is a string terminator in your array.
If you can use a debugger you will find that all values are in your array, its just that printf will stop at '\0'
Just move your string iterator back one char due to '\0' (after you execute while(*s++ != '\0');) and that fixes your code.
Explanation:
Your s string is "abcde\0". After the first while loop, the iterator will be at '\0'. If you leave it there you will concatenate both strings obtaining the result "abcde\0fghi\0" which prints "abcde" due to the first '\0'.
Instead, if you move back the s string iterator one position with (s--) you will have this string as result "abcdefghi\0" which prints the string as you expect.
Fixed Code:
#include<stdio.h>
char * sstrcat(char*,char*);
void main() {
char *c;
char s[100] = "abcde";
char t[] = "fghi";
c = sstrcat(s,t);
printf("%s\n",c);
}
char* sstrcat(char *s,char *t) {
char* temp = s;
while(*s++ != '\0');
s--;
while((*s++ = *t++) != '\0');
return temp;
}
Related
Cannot figure out why the program doesn't work when parameters are the same character string.
int main (void) {
char s[] = "123";
strcat(s, s);
return 0;
}
void strcat (char *s, char *t) {
int len = strlen(s);
while (*t != '\0')
*(s + len++) = *t++;
*(s + len) = '\0';
}
You need spare room in the first string to concatenate the second string. And you are modifying the same memory that you are reading from. And as you do, you are removing the termination char so this would likely end up in an infinite loop.
I am working on a string reversal problem where I am trying to swap values from two ends with one another. As a part of the reverse function, I have a line that checks whether the pointer has reached the end-of-string character (in the form of while(*end!= '\0')). However, this doesn't seem to be working, and at the end of the while loop when I de-reference "end" I get blank. When I use (while(*end)), everything works perfectly but I have to then decrement my pointer "end" to make sure I am accessing the last element of my string. Why can't I check the pointer against the string literal '\0'?
#include<stdio.h>
void reverse(char* s);
void main(){
char str[]="abcdef";
printf("%s\n",str);
reverse(str);
printf("%s\n",str);
}
void reverse(char* p){
char* start = p;
char* end = p;
char tmp;
int length =0;
while(*end!='\0'){
end+=1;
length+=1;
}
printf("%c\n",*end); // problem line
int c;
for (c = 0; c < length/2; c++)
{
tmp = *start;
*start = *end;
*end = tmp;
start++;
end--;
}
//printf("%s\n",p);
}
In the //Problem line the value of *end is '\0' - You should print the integer value of '\0' to verify which is 0 & it works - apart from that you'll need to uncomment the } from reverse function.
'\0' is a non printable character: Reference: Non-printable and Printable ASCII Characters
#include <stdio.h>
#include <string.h>
size_t mystrlen(const char *str)
{
const char *ptr = str;
while(*ptr++);
return ptr - str;
}
char *reverse(char *str)
{
size_t len = mystrlen(str);
char *end = str + len -1;
char *saved = str;
len /= 2;
while(len--)
{
char tmp = *str;
*str++ = *end;
*end-- = tmp;
}
return saved;
}
int main(void)
{
char str[] = "This is the string which will be reversed";
printf("%s\n", reverse(str));
}
your code works. end reaches '\0'. but printf prints string until the first '\0'. so your print appears empty. if you add after the while loop:
--end;
or change the while to: while(*(end+1))
your code will do what you want it to
You don't need the length variable, and you can use pre-decrement on end.
#include <stdio.h>
void reverse(char *start);
int main(void) {
char str[]= "abcdef";
printf("%s\n", str);
reverse(str);
printf("%s\n", str);
}
void reverse(char* start) {
char *end = start;
while(*end != '\0') {
end++;
}
while(start < end) {
char temp = *--end;
*end = *start;
*start++ = temp;
}
}
I am concatenating a string (t) at the end of another string (s) in this code but stuck in the use of operators and their precedence in the loop ( while() )
1.while(*s++); doesn't do the work
2.while(*s) ++s; does
But what is the difference between them ?
#include<stdio.h>
void strcat(char *, const char *);
int main(void){
char s[100] = "Aditya ";
char t[100] = "Kumar";
strcat(s, t);
printf("%s ", s);
return 0;
}
void strcat(char * s, const char * t){
while(*s)
s++;
while(*s++ = *t++);
}
Why in the strcat() function in first while while(*s++); doesn't concatenate the string but while(*s) s++; does I guess they work the same way ?
they aren't equivalent.
while(*s++);
increments the pointer no matter what, so when *s is \0, the pointer is incremented once more. And the concatenation happens after the nul-terminator. The rest of the buffer contains zeroes so it doesn't crash but it doesn't do the job.
while(*s) { s++; }
stops when *s is \0. So no extra incrementation is performed.
I'm attempting to remove a character from a string in C. The problem I am having with my code is that it removes the first instance of the character from the string but also wipes everything after that character in the string too. For example, removing 'l' from 'hello' prints 'he' rather than 'heo'
int i;
char str1[30] = "Hello", *ptr1, c = 'l';
ptr1 = str1;
for (i=0; i<strlen(str1); i++)
{
if (*ptr1 == c) *ptr1 = 0;
printf("%c\n", *ptr1);
ptr1++;
}
I need to use pointers for this and would like to keep it as simple as possible since I'm a beginner in C.
Thanks
You can do it like this:
void remove_all_chars(char* str, char c) {
char *pr = str, *pw = str;
while (*pr) {
*pw = *pr++;
pw += (*pw != c);
}
*pw = '\0';
}
int main() {
char str[] = "llHello, world!ll";
remove_all_chars(str, 'l');
printf("'%s'\n", str);
return 0;
}
The idea is to keep a separate read and write pointers (pr for reading and pw for writing), always advance the reading pointer, and advance the writing pointer only when it's not pointing to a given character.
If you remove the characters in place you will have to shift the rest of the string one place to the left every time you remove a character, this is not very efficient. The best way is to have a second array that takes the filtered string. For example you can change your code like this.
int i;
char str1[30] = "Hello", *ptr1, c = 'l';
char str2[30] = {0}, *ptr2;
ptr1 = str1;
ptr2 = str2;
for (i=0; i<strlen(str1); i++)
{
if (*ptr1 != c) *ptr2++=*ptr1;
ptr1++;
}
printf("%s\n", str2);
The problem is that when you encounter the first character that matches c, you insert a null character right there. That means you're essentially cutting off the rest of the string.
What you need to do is when you find a matching character, move the following characters back one position. Then you need to insert the null character at the very end depending on how many characters you have removed.
char str1[30] = "Hello", *prt1, c = 'l';
char str2[30], *prt2;
prt1 = str1;
prt2 = str2;
while(*prt1 != 0)
{
if(*prt1 != c)
{
*prt2 = *prt1;
prt2++;
}
prt1++;
}
*prt2 = '\0';
i know that it is a type of duplicate answer, but this code is function's version for solving the problem. I thought that as the questioner was a beginner, he might learn much from decomposed version of problem.
int del_x_char(char *p, int x)
{
char *q;
x=first_occurance(p, 'i')/*you can replace any character that you want delete with 'i'*/
q=p+x;
while(*q=*(q+1))
q++;
*q='\0';
return 0;
}
int first_occurance(char *q, char phar)
{
int i=0;
while(*q)
{
if(*q++==phar)
return i;
i++;
}
return -1;
}
just change
if (*ptr1 == c) *ptr1 = 0;
to
if (*ptr1 == c) continue;
as #ouah said, it breaks at the first NULL character..
C defines a string as "a contiguous sequence of characters terminated by and including the first null character"
How can I strip a string with all \n and \t in C?
This works in my quick and dirty tests. Does it in place:
#include <stdio.h>
void strip(char *s) {
char *p2 = s;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
int main() {
char buf[] = "this\t is\n a\t test\n test";
strip(buf);
printf("%s\n", buf);
}
And to appease Chris, here is a version which will make a place the result in a newly malloced buffer and return it (thus it'll work on literals). You will need to free the result.
char *strip_copy(const char *s) {
char *p = malloc(strlen(s) + 1);
if(p) {
char *p2 = p;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
return p;
}
If you want to replace \n or \t with something else, you can use the function strstr(). It returns a pointer to the first place in a function that has a certain string. For example:
// Find the first "\n".
char new_char = 't';
char* pFirstN = strstr(szMyString, "\n");
*pFirstN = new_char;
You can run that in a loop to find all \n's and \t's.
If you want to "strip" them, i.e. remove them from the string, you'll need to actually use the same method as above, but copy the contents of the string "back" every time you find a \n or \t, so that "this i\ns a test" becomes: "this is a test".
You can do that with memmove (not memcpy, since the src and dst are pointing to overlapping memory), like so:
char* temp = strstr(str, "\t");
// Remove \n.
while ((temp = strstr(str, "\n")) != NULL) {
// Len is the length of the string, from the ampersand \n, including the \n.
int len = strlen(str);
memmove(temp, temp + 1, len);
}
You'll need to repeat this loop again to remove the \t's.
Note: Both of these methods work in-place. This might not be safe! (read Evan Teran's comments for details.. Also, these methods are not very efficient, although they do utilize a library function for some of the code instead of rolling your own.
Basically, you have two ways to do this: you can create a copy of the original string, minus all '\t' and '\n' characters, or you can strip the string "in-place." However, I bet money that the first option will be faster, and I promise you it will be safer.
So we'll make a function:
char *strip(const char *str, const char *d);
We want to use strlen() and malloc() to allocate a new char * buffer the same size as our str buffer. Then we go through str character by character. If the character is not contained in d, we copy it into our new buffer. We can use something like strchr() to see if each character is in the string d. Once we're done, we have a new buffer, with the contents of our old buffer minus characters in the string d, so we just return that. I won't give you sample code, because this might be homework, but here's the sample usage to show you how it solves your problem:
char *string = "some\n text\t to strip";
char *stripped = strip(string, "\t\n");
This is a c string function that will find any character in accept and return a pointer to that position or NULL if it is not found.
#include <string.h>
char *strpbrk(const char *s, const char *accept);
Example:
char search[] = "a string with \t and \n";
char *first_occ = strpbrk( search, "\t\n" );
first_occ will point to the \t, or the 15 character in search. You can replace then call again to loop through until all have been replaced.
I like to make the standard library do as much of the work as possible, so I would use something similar to Evan's solution but with strspn() and strcspn().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SPACE " \t\r\n"
static void strip(char *s);
static char *strip_copy(char const *s);
int main(int ac, char **av)
{
char s[] = "this\t is\n a\t test\n test";
char *s1 = strip_copy(s);
strip(s);
printf("%s\n%s\n", s, s1);
return 0;
}
static void strip(char *s)
{
char *p = s;
int n;
while (*s)
{
n = strcspn(s, SPACE);
strncpy(p, s, n);
p += n;
s += n + strspn(s+n, SPACE);
}
*p = 0;
}
static char *strip_copy(char const *s)
{
char *buf = malloc(1 + strlen(s));
if (buf)
{
char *p = buf;
char const *q;
int n;
for (q = s; *q; q += n + strspn(q+n, SPACE))
{
n = strcspn(q, SPACE);
strncpy(p, q, n);
p += n;
}
*p++ = '\0';
buf = realloc(buf, p - buf);
}
return buf;
}