I'm wondering what's occurring here, I allocate space for the dest variable outside of the reverse function. And then write to it in the function call. But my output is blank. I want to do this without malloc, purely for educational purposes. Thanks
#include <stdio.h>
#include <string.h>
/*function declaration*/
void reverse(char *src, char *dest);
int main(void) {
char src[] = "hello, world";
char dest[strlen(src)];
reverse(src, dest);
printf("%s\n", dest);
return 0;
}
/*function reverse a string*/
void reverse(char *src, char *dest) {
int i;
int j = 0;
for(i = strlen(src); i >= 0; i--) {
*(dest+j) = *(src+i);
++j;
}
}
1) Since your iteration starts with
for(i = strlen(src); i >= 0; i--) {
it assigns 0 to the dest, thus terminating the string. So printf() prints nothing as it sees the 0 terminator. You can re-write it as:
for(i = strlen(src) - 1; i >= 0; i--) {
*(dest+j) = *(src+i);
++j;
}
dest[j] = 0; /* terminates the string */
2) You have another problem. Your dest doesn't have enough space. It should be:
char dest[strlen(src) + 1]; /* Notice the +1 */
3) You should use size_t for array indexes instead of int.
You are forgetting about the null character in your strings. dest is not large enough to hold the reverse of the string since there needs to be a null-terminator:
char dest[ strlen(src) + 1 ];
Then in the loop you are copying the null-terminator to the front of the string so it is essentially the string "" but using more memory. You need to start at the index strlen() - 1:
for(i = strlen(src)-1; i >= 0; i-- ){
The problem is with the for(i=strlen(src)..... in reverse(). src[strlen(src)] is 0 (zero; string-termination). So when you get to printf(), it sees the firs char and outputs an empty string.
Use strlen(str)-1, and then *(dest+j) = 0 after the for-loop.
In total, reverse() should be:
void reverse(char *src, char *dest) {
int i;
int j = 0;
for(i = strlen(src)-1; i >= 0; i--) {
*(dest+j) = *(src+i);
++j;
}
*(dest+j) = 0;
}
Related
I am having trouble with the very last line in my function, where I am stilly learning the basics of C. I have the signature of this function given and am tasked to write a function to concatenate two strings. The commented line outputs the correct result.
#include <stdio.h>
#include <stdlib.h>
// 1) len = dst-len + max_dst_len
int strlcat(char *dst, const char *src, int max_dst_len) {
int len = 0;
while (dst[len] != '\0') {
len++;
}
int total_len = len + max_dst_len;
char *new_str = malloc(sizeof(char) * total_len);
for (int i = 0; i < len; i++) {
new_str[i] = dst[i];
}
for (int i = len; i < total_len; i++) {
new_str[i] = src[i - len];
}
new_str[total_len] = '\0';
//printf("%s <--\n", new_str);
dst = *new_str;
return total_len;
}
int main() {
char test1[] = "dst";
char test1src[] = "src";
printf("%s\n", test1);
printf("%d\n", strlcat(test1, test1src, 10));
printf("%s\n", test1);
}
You should not be adding max_dst_len to the length of dst. max_dst_len is the amount of memory that's already allocated in dst, you need to ensure that the concatenated string doesn't exceed this length.
So you need to subtract len from max_dst_len, and also subtract 1 to allow room for the null byte. This will tell you the maximum number of bytes you can copy from src to the end of dst.
In your main() code, you need to declare test1 to be at least 10 bytes if you pass 10 as the max_dst_len argument. When you omit the size in the array declaration, it sizes the array just big enough to hold the string you use to initialize it. It's best to use sizeof test1 as this argument, to ensure that it's correct for the string you're concatenating to.
#include <stdio.h>
int strlcat(char *dst, const char *src, int max_dst_len) {
int len = 0;
while (dst[len] != '\0') {
len++;
}
int len_to_copy = max_dst_len - len - 1;
int i;
for (i = 0; i < len_to_copy && src[i] != '\0'; i++) {
dst[len+i] = src[i];
}
dst[i] = '\0';
//printf("%s <--\n", new_str);
return i + len;
}
int main() {
char test1[6] = "dst";
char test1src[] = "src";
printf("%s\n", test1);
printf("%d\n", strlcat(test1, test1src, sizeof test1));
printf("%s\n", test1);
}
#include<stdio.h>
#include<conio.h> //**Just To Add getch() function**
int length(char *p){
int i; //**I know That these variable are not the same as they are in other function**
for(i=0;*(p+i)!='\0';i++);
return i;
}
void strrev(char *p){
int i,len;
len=length(p);
char cpy[len]; //**Already Tried to change it to some fixed value**
for(i=0;i<len;i++){
cpy[i]=*(p+len-i);
}
for(i=0;i<len;i++){
*(p+i)=cpy[i];
}
}
int main(){
char str[20]="computer";
strrev(str);
printf("%s",str);
getch(); //**to Stop The Screen**
return 0;
}
I have tried changing the array size to a fixed value i also tried with changing the variable but there is no mistake in my syntax.
By recommendation of #Yunnosch, here is my comment as an answer.
In your function strrev you iterate over the whole string i.e. the iterations for i from zero to len / 2 you correctly grab the characters, but the remaining iterations just undo this again.
Thus, just iterate from zero to len >> 1. The bit-shift ensures integer division.
void strrev(char* const str)
{
const size_t len = strlen(str);
for(size_t i = 0; i < (len >> 1u); ++i)
{
const size_t j = len - 1u - i;
char c = str[i];
str[i] = str[j];
str[j] = c;
}
}
using this cpy[i]=*(p+len-i); means you are placing \0 terminator in the beginning of string cpy. in which case your both of strings will start with \0 and so printf will do nothing.
so change cpy[i]=*(p+len-i); to cpy[i] = *(p + len - i-1);.
I'm trying to figure out how to copy a trimmed string with leading whitespaces removed and store into dest array using pointer / without a pointer.
This is what I tried.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void trim_copy(char dest[], char src[]){
char *p = src;
size_t i;
size_t counter = 0;
size_t length = strlen(src);
while(!isspace(src[counter]) && counter < length){
p++;
counter++; /*move the pointer to next index of string if it's a space*/
}
for (i = 0; i< length-counter; i++) {
dest[i] = *p;
p++;
}
}
int main(void){
char string_with_space_dest[20];
ltrim_copy(string_with_space_dest, " hello");
printf("after removing leading space %s\n",string_with_space_dest );
return 0;
}
Prints out:
after removing leading space hello
It compiles, but not working at all.
what if the src array was const and you can't use a pointer?
void trim_copy(char dest[], const char src[]){}
isspace function is used to check if the argument contains any whitespace characters, so you need to remove the not operator because you want to skip the spaces and at the end after copying into dest array you need to assign the null character to dest array.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void ltrim_copy(char dest[], char src[]){
char *p = src;
size_t i;
size_t counter = 0;
size_t length = strlen(src);
while(isspace(src[counter]) && counter < length){
p++;
counter++; /*move the pointer to next index of string if it's a space*/
}
for (i = 0; i< length-counter; i++) {
dest[i] = *p;
p++;
}
dest[i] = '\0';
}
int main(void){
char string_with_space_dest[20];
ltrim_copy(string_with_space_dest, " hello");
printf("after removing leading space %s\n",string_with_space_dest );
return 0;
}
I am trying to have this output:
Comparing results of concat and strcat ...
strcmp("Plain old stringTroy", "Plain old stringTroy") says: 0
The strcmp returns 0 if the two string arguments are identical. If the result is 0, then the concat behaves exactly like the library function strcat.
this is what I have for concat method.
#define MAXSIZE 32
void concat(char dest[], char src[])
{
int i=length(src);
int j=0;
for(j; j<src[j] !='\0'; j++) {
dest[i+j] = src[j];
}
dest[i+j] = '\0';
}
length method is:
int length(char str[])
{
// Add code here to return the length of the
// string str without using the strlen function
// Do not count the null character '\0'
// in computing the length of the string
int len=0;
int i;
for(i=0;i<str[i];i++) {
len++;
}
return len;
}
This is my main
int main()
{
// Variable declarations for all parts
char str2[] = "Troy";
char str4[] = "Plain old string";
char str6[MAXSIZE];
// Part 6
printf("\n----- Part 6 -----\n");
// Make a copy of the destination string first, to be reused later
strcpy(str6, str4);
concat(str4, str2);
strcat(str6, str2);
printf("Comparing results of concat and strcat ...\n");
printf("strcmp(\"%s\", \"%s\") says: %d\n",
str4, str6, strcmp(str4, str6)
);
return 0;
}
This is my output when I run it:
----- Part 6 -----
Comparing results of concat and strcat ...
strcmp("PlaiTroy", "Plain old stringTroy") says: -1
The first string is not the same as the second string which is why I am getting a -1. My problem is in my concat method but I can't seem to understand why it won't execute well. Is it because of the spaces? Is 0 and '\0' not executing well?
There are multiple problems in your code:
The loop test in the length function is incorrect: instead of i < str[i], it should be:
for (i = 0; str[i] != '\0'; i++)
the same problem in the concat function. Change the loop to:
for (j = 0; src[j] != '\0'; j++) {
also in the concat function, i should be the length of dst, not that of src. You might use len instead of i for this variable.
The array str4 in function main does not have any space available at the end for concat to append anything. Define it with a larger size this way:
char str4[MAXSIZE] = "Plain old string";
Here is the corrected version:
#include <stdio.h>
#include <string.h>
#define MAXSIZE 32
void concat(char dest[], char src[]) {
int len = length(dest);
int j;
for (j = 0; src[j] != '\0'; j++) {
dest[len + j] = src[j];
}
dest[len + j] = '\0';
}
int length(char str[]) {
int len = 0;
int i;
for (i = 0; i < str[i]; i++) {
len++;
}
return len;
}
int main(void) {
// Variable declarations for all parts
char str2[MAXSIZE] = "Troy";
char str4[MAXSIZE] = "Plain old string";
char str6[MAXSIZE];
// Part 6
printf("\n----- Part 6 -----\n");
// Make a copy of the destination string first, to be reused later
strcpy(str6, str4);
concat(str4, str2);
strcat(str6, str2);
printf("Comparing results of concat and strcat ...\n");
printf("strcmp(\"%s\", \"%s\") says: %d\n",
str4, str6, strcmp(str4, str6));
return 0;
}
You have several problems in both functions:
concat
for(j; j<src[j] !='\0'; j++) {
What is the for exit condition here?, src[j] != '\0' is enough.
dest[i+j] = src[j];
Here you add data with an offset of i, but I is the length of src, not dst.
So the corrected function could be:
void concat(char dest[], char src[])
{
/* descriptive variable name */
int len_dst = length(dst);
int j=0;
/* clear exit condition */
for(; src[j] != '\0'; j++) {
dest[len_dst+j] = src[j];
}
dest[len_dst+j] = '\0';
}
length
for(i=0;i<str[i];i++) {
Same remark, what is this exit condition? src[i] != '\0' is enough
So the corrected function could be:
int length(char str[])
{
int len=0;
int i;
/* clear exit condition */
for ( i=0; str[i] != '\0'; i++) {
len++;
}
return len;
}
main
And warning in main function:
char str4[] = "Plain old string";
concat(str4, str2); /* <- erases what is after str4 */
You do not have enough space to store result. Write something like:
char str2[] = "Troy";
char str4[MAXSIZE] = "Plain old string"; /* <-- reserve spaces after str4*/
/* ... */
concat(str4, str2);
I'm supposed to copy char orig[] to char reversed[] and reverse it. My function works but doesn't properly reset the string as evidenced by the fact that a blank string returns the prior test results. How can I fix this?
void reverse(char orig[], char reversed[]) {
int lastChar = strlen(orig) - 1;
int lastCopy = lastChar;
int i;
for(i = 0; i < lastChar; i++){
reversed[lastCopy] = orig[i];
reversed[i] = orig[lastCopy];
lastCopy--;
reversed[lastChar+1] = '\0';
}
return ;
}
This is what I get as output:
Test "software" (Pass, returns: erawtfos)
Test the empty string
Assertion failure
Have: <erawtfos>
Expect: <>
Test a long string (Pass)
Test a simple palindrome (Pass)
4 assertions: 3 passed 1 failed
OP problem: When the original string orig has length 0 or 1, the null character is never set in reversed.
Instead create a simple loop pulling 1 char at a time.
// As `orig` elements are not changed, good C style to make it `const`
void reverse(const char orig[], char reversed[]) {
// use `size_t` as `int` may be too narrow
size_t length = strlen(orig);
size_t i;
for(i = 0; i < length; i++) {
reversed[i] = orig[length - i - 1];
}
reversed[i] = '\0';
}
If orig and reversed might overlap, a temporary copy is needed.
void reverse(const char orig[], char reversed[]) {
size_t length = strlen(orig);
char tmp[length+1]; // Add 1 because an array of size 0 is UB
memcpy(tmp, orig, length);
size_t i;
for(i = 0; i < length; i++) {
reversed[i] = tmp[length - i - 1];
}
reversed[i] = '\0';
}
Simplify:
void reverse(char orig[], char reversed[]) {
int len = strlen(orig);
int last = len - 1;
reversed[len] = '\0';
for (int i = 0; i < len; i += 1) {
reversed[last] = orig[i];
last -= 1;
}
return;
}
you can use built in functions like string::rbegin(),string::rend()
in order to copy string reversely.
string copy(orig.rbegin(),orig.rend());
don't forget to include < string.h >