I have a problem with my code below, I am trying to reverse a string, but I have run time error, anyone who can help me check it? The problem is:
eg:
INPUT: char *s = "This is my string"
OUTPUT: "string my is This"
#include <iostream>
using namespace std;
void reverse(char *str, int start, int end){
char tmp;
while(end > start){
tmp = str[end];
str[end] = str[start];
str[start] = tmp;
end--;
start++;
}
}
int main()
{
char *s = "This is my string";
int len = strlen(s);
int start = 0;
int end = len-1;
reverse(s, start, end);
printf("%s", s);
end = 0;
while( end < len){
if(s[end] == ' '||s[end] =='\0'){
while(s[start]==' ')
start++;
reverse(s,start,end-1);
start = end;
}
end++;
}
printf("%s", s);
cin.get();
}
You cannot modify this string:
char *s = "This is my string";
You've declared it incorrectly, it should be
const char* = "This is my string";
Normally these strings are allocated in a region of memory which you cannot write to. You should create another buffer to write the reversed string to.
Related
I am trying to write a program without using string library in C which can replace the spaces in string with 'XXX'.
I have done this much but did not getting idea after this.
char buff[100];
int i;
char *my_func(char *arr){
for( i=0;arr[i]!='\0';i++){
if(arr[i]==' '){
buff[i]='X';
break;
}
else{
buff[i]=arr[i];
}
}
buff[i+1]='X';
buff[i+2]='X';
return buff;
}
int main()
{
char arr[]="This is my string";
my_func(arr);
printf("%s",buff);
return 0;
}
You need to track the indices for your source and destination buffers separately, since encountering a space in the source string will cause the resulting string to grow disproportionately.
Those character assignments should be inside inside the loop.
Don't forget to NUL terminate your destination buffer.
Avoid global variables when possible.
#include <stdio.h>
char *replace(char *dest, char *src) {
size_t j = 0;
for (size_t i = 0; src[i]; i++) {
if (src[i] == ' ') {
dest[j++] = 'X';
dest[j++] = 'X';
dest[j++] = 'X';
} else
dest[j++] = src[i];
}
dest[j] = '\0';
return dest;
}
int main(void) {
char arr[] = "This is my string.";
char buffer[256];
replace(buffer, arr);
printf("[%s] --> [%s]\n", arr, buffer);
}
Output:
[This is my string.] --> [ThisXXXisXXXmyXXXstring.]
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 know this question is extremely common and the solution is well-known. But for a long time, I am getting an error I cannot figure out. I am trying to reverse a string in C. My code is given below:
#include <stdio.h>
char *reverse(char *);
int main(void) {
char str[] = "Hello";
char *rev;
rev = reverse(str);
printf("The reversed string is %s", rev);
return 0;
}
char *reverse(char *str){
char *end = str;
char tmp;
if(str){
while(*end){
++end;
}
--end;
while(str < end){
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
return str;
}
As result, I am getting "leH", not "olleH". Can anyone point out why?
The pointer str you return in reverse() does not point to the beginning of the string, but somewhere in the middle at the end of the loop.
Another problem with your function is in case you pass an empty string: end is decremented from the end of the string and points outside the string. This invokes undefined behaviour.
You should use 2 temporary pointers to perform the task:
char *reverse(char *str) {
if (str && *str) {
char *p = str;
char *end = p + strlen(p) - 1;
while (p < end) {
char tmp = *p;
*p++ = *end;
*end-- = tmp;
}
}
return str;
}
Or if you prefer to use index variables:
char *reverse(char *str) {
if (str && *str) {
for (size_t i = 0, j = strlen(str); i < --j; i++) {
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
}
}
return str;
}
Because you return the incremented pointer, use another pointer or index notation and it will work, like this
char *reverse(char *str)
{
char *end;
char tmp;
int i;
end = str;
if ((str == NULL) || (*str == '\0'))
return str;
while (*end != 0)
++end;
--end;
i = 0;
while (str + i < end)
{
tmp = str[i];
str[i++] = *end;
*end-- = tmp;
}
return str;
}
When you return str, it's no longer pointing at the beginning of the string.
Another way of achieving reversing string is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *reverse(const char *);
int main(void){
char *s = "hello world";
char *s_rev = reverse(s);
printf("%s => %s", s, s_rev);
free(s_rev);
return 0;
}
char *reverse(const char *s){
char *s_new = strdup(s);
char *s_begptr = &s[0];
char *s_endptr = &s[strlen(s) - 1];
char *ptr = NULL;
for (ptr = s_endptr; ptr >= s_begptr; ptr--, s_new++){
*s_new = *ptr;
}
*s_new = '\0';
s_new -= strlen(s);
return s_new;
}
Notice we are not using any temporary variables to store the value, rather, using both start and end pointers of the same string and using the loop to work backwards from the end of string in reverse.
I have a string in my program where in which it need to be altered with another string value before a "/".
Source String : qos-tree/output_rate
Target String : qos-tree-2/output_rate
#include <stdio.h>
#include <string.h>
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main(void)
{
char str[256] = "qos-tree/output_rate";
char c = "a";
append(str, c);
printf("%s\n", str);
return 0;
}
This is what i have done so far,I think the logic is wrong here.Can anyone guide me to correct it?
Once the execution is completed the source string should have a "-2" before the "/"
void insert_before_ch(char *s, const char *ins, char c){
char *p = strchr(s, c);
if(p){
size_t len = strlen(ins);
memmove(p + len, p, strlen(p)+1);
memcpy(p, ins, len);
}
}
int main(void){
char str[256] = "qos-tree/output_rate";
insert_before_ch(str, "-2", '/');
printf("%s\n", str);
return 0;
}
In your attempt, you don't look for a slash and I do not see any "-2" anywhere.
Try this instead:
#include <stdio.h>
#include <string.h>
void append(char* s, char del, char* substring) {
char origin[256];
strcpy(origin, s);
int i = 0, j = 0, z = 0;
for(; origin[i]; ++i) {
if(origin[i] != del) {
s[j++] = origin[i];
} else {
for(; substring[z]; ++z) {
s[j++] = substring[z];
}
s[j++] = origin[i];
}
}
s[j] = '\0';
}
int main(void) {
char str[256] = "qos-tree/output_rate";
char del = '/';
char* substring = "-2";
append(str, del, substring);
printf("%s\n", str);
return 0;
}
The logic is that inside the function we use origin array to remember the actual contents of the array and then we copy from origin to s (which is the actual array of main()). If we find our delimiter del, then we copy the substring in that position and continuing with copying.
Note that the length of the array should be enough to store the resulted string. In this case, it is.
I think you should make your function work with dynamic allocation, because inserting characters into the string will make the resulting string larger, so this is my suggestion
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void insert(char **str, char chr, unsigned int position)
{
int length;
char *ptr;
if (str == NULL)
return;
length = strlen(*str);
if (position >= length)
return;
ptr = realloc(*str, 2 + length);
if (ptr == NULL)
return;
*str = ptr;
memmove(ptr + position + 1, ptr + position, length - position + 1);
ptr[position] = chr;
}
int main(void)
{
const char *source = "qos-tree/output_rate";
size_t length = strlen(source);
char *str = malloc(1 + length);
if (str == NULL)
return -1;
strcpy(str, source);
insert(&str, '-', 8);
insert(&str, '2', 9);
printf("%s\n", str);
free(str);
return 0;
}
first of all thist char c = "a" should be replace with this char c = 'a'; because c is a character not a string
as for your problem I didn't realy see the relation between what your code is doing with what you said you wanted to do , but here a piece of code to achieve what , I think , you want to do :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void append(char* str , char c)
{
char firststr[60];
char therest[30];
strcpy(firststr , strtok(str , "/"));
strcpy(therest , strtok(NULL , "/"));
strcat(firststr , &c);
strcat(firststr , "/");
strcat(firststr , therest);
strcpy(str , firststr);
}
int main(void)
{
char str[60] = "qos-tree/output_rate";
char c = '2';
append(str , c);
printf("%s\n" , str);
}
there you go I think this is what you wanted to do you can modify the array sizes to fit your needs
I want to split a String in C.
My String is defined by my Struct:
struct String
{
char *c;
int length;
int maxLength;
}
Then I have a function that does the splitting. Perhaps C has something that does this, but although I wanted my own, I have not found anything that will do it so far.
String ** spliter(String *s)
{
if(s == NULL)
return NULL;
// set of splitters: {'\n', ' '}
}
Input looks something like this: This is Sparta.
Then I want to return a pointer to each character array.
*p1 = This
*p2 = is
*p3 = Sparta.
If that makes any sense, I want an array of pointers, and each pointer points to a character array.
I will have to realloc the String as I increment the size of each character array. Probably my biggest problem is imagining how the pointers work.
Similar problem: c splitting a char* into an char**
So, how do I go about doing this?
#include <string>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string test = "aa aa bbc cccd";
vector<string> strvec;
string strtemp;
string::size_type pos1, pos2;
pos2 = test.find(' ');
pos1 = 0;
while (string::npos != pos2)
{
strvec.push_back(test.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
pos2 = test.find(' ', pos1);
}
strvec.push_back(test.substr(pos1));
vector<string>::iterator iter1 = strvec.begin(), iter2 = strvec.end();
while (iter1 != iter2)
{
cout << *iter1 << endl;
++iter1;
}
return 0;
}
Have you looked at strtok? It should be possible to do this using strtok.
here is a exemple :
String ** spliter(String *s)
{
int i;
int j;
char *p1;
char *p2;
char *p3;
i = 0;
j = 0;
if(s == NULL)
return NULL;
p1 = malloc(sizeof(*p1) * strlen(s));
p2 = malloc(sizeof(*p2) * strlen(s));
p3 = malloc(sizeof(*p3) * strlen(s));
while (s[i] != ' ')
{
p1[j++] = s[i];
i++;
}
i++;
j = 0;
while (s[i] != ' ')
{
p2[j++] = s[i];
i++;
}
i++;
j = 0;
while (s[i] != '\0')
{
p3[j++] = s[i];
i++;
}
printf("%s\n", p1);
printf("%s\n", p2);
printf("%s\n", p3);
}
You're looking for strtok, check out man 3 strtok, or here if you're not on *nix.
You would use it like this: (Assuming that you can write the add_string code yourself.)
String ** spliter(String *s)
{
if(s == NULL)
return NULL;
String **return_strings = NULL;
char *delim = " \n";
char *string = strtok(s, delim);
int i = 0;
for(i = 0; add_string(return_strings, string, i) != -1; i++) {
string = strtok(NULL, delim);
}
return strings;
}
Note that if you need to save the original string (strtok modifies the string it works on), you'll need to call strdup on the original string, then operate on the copy.
EDIT: OP said he was having trouble thinking about the pointers. With the above code sample, add_string only has to worry about dealing with a string of characters, as opposed to an array of pointers to pointers to characters. So it might look something like this:
int add_string(String **strings, char *s, int len)
{
if(s == NULL)
return -1;
String *current_string = NULL;
strings = realloc(strings, sizeof(String) * (len + 1));
current_string = strings[len];
/* fill out struct fields here */
}
add strdup and strtok can work on a copy of the string. The split() call is more generic than the other spliter() examples, but does the same thing with strtok on a duplicate.
char **
split(char **result, char *w, const char *src, const char *delim)
{
int i=0;
char *p;
strcpy(w,src);
for(p=strtok(w, delim) ; p!=NULL; p=strtok('\0', delim) )
{
result[i++]=p;
result[i]=NULL;
}
return result;
}
void display(String *p)
{
char *result[24]={NULL};
char *w=strdup(p->c);
char **s=split(result, w, p->, "\t \n"); split on \n \t and space as delimiters
for( ; *s!=NULL; s++)
printf("%s\n", *s);
free(w);
}