Cmag
Cmag

Reputation: 15760

C replace char in char array

Folks, need to search through a character array and replace any occurrence of '+','/',or'=' with '%2B','%2F', and '%2F' respectively

base64output variable looks like

FtCPpza+Z0FASDFvfgtoCZg5zRI=

code

char *signature = replace_char(base64output, "+", "%2B");
signature = replace_char(signature, "/", "%2F");
signature = replace_char(signature, "=", "%3B");

char replace_char (char *s, char find, char replace) {
    while (*s != 0) {
        if (*s == find)
        *s = replace;
        s++;
    }
    return s;
}

(Errors out with)

   s.c:266: warning: initialization makes pointer from integer without a cast

What am i doing wrong? Thanks!

Upvotes: 5

Views: 24866

Answers (6)

Ammar Hourani
Ammar Hourani

Reputation: 71

below is a code that ACTUALLY WORKS !!!!

Ammar Hourani

char * replace_char(char * input, char find, char replace) 
{

char * output = (char*)malloc(strlen(input));

for (int i = 0; i < strlen(input); i++)
{
    if (input[i] == find) output[i] = replace;
    else output[i] = input[i];
}

output[strlen(input)] = '\0';

return output;
}

Upvotes: 0

asveikau
asveikau

Reputation: 40246

You could go for some length discussing various ways to do this.

Replacing a single char is simple - loop through, if match, replace old with new, etc.

The problem here is that the length of the "new" part is longer than the length of the old one.

One way would be to determine the length of the new string (by counting chars), and either (1) try to do it in place, or (2) allocate a new string.

Here's an idea for #1:

int replace(char *buffer, size_t size, char old, const char *newstring)
{
   size_t newlen = strlen(newstring);
   char *p, *q;
   size_t targetlen = 0;

   // First get the final length
   //
   p = buffer;
   while (*p)
   {
      if (*p == old)
         targetlen += newlen;
      else
         targetlen++;
      ++p;
   }

   // Account for null terminator
   //
   targetlen++;

   // Make sure there's enough space
   //
   if (targetlen > size)
      return -1;

   // Now we copy characters.  We'll start at the end and
   // work our way backwards.
   //
   p = buffer + strlen(buffer);
   q = buffer + targetlen;

   while (targetlen)
   {
      if (*p == old)
      {
         q -= newlen;
         memcpy(q, newstring, newlen);
         targetlen -= newlen;
         --p;
      }
      else
      {
         *--q = *p--;
         --targetlen;
      }
   }

   return 0;
}

Then you could use it this way (here's a quick test I did):

char buf[4096] = "hello world";

if (replace(buf, sizeof(buf), 'o', "oooo"))
{
   fprintf(stderr, "Not enough space\n");
}
else
{
   puts(buf);
}

Upvotes: 3

BLUEPIXY
BLUEPIXY

Reputation: 40145

fix like this

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *replace_char (char *str, char find, char *replace) {
    char *ret=str;
    char *wk, *s;

    wk = s = strdup(str);

    while (*s != 0) {
        if (*s == find){
            while(*replace)
                *str++ = *replace++;
            ++s;
        } else
            *str++ = *s++;
    }
    *str = '\0';
    free(wk);
    return ret;
}

int main(void){
    char base64output[4096] = "FtCPpza+Z0FASDFvfgtoCZg5zRI=";
    char *signature = replace_char(base64output, '+', "%2B");
    signature = replace_char(signature, '/', "%2F");
    signature = replace_char(signature, '=', "%3B");
    printf("%s\n", base64output);

    return 0;
}

Upvotes: 1

Joe DF
Joe DF

Reputation: 5548

1.

  • for char use '' single quotes

  • for char* use "" double quotes

2.

  • The function does include the return keyword, therefore it does not return what you'd expect

3.

Upvotes: 3

yoones
yoones

Reputation: 2474

If the issue is that you have garbage in your signature variable:

void replace_char(...) is incompatible with signature = replace_char(...)

Edit:

Oh I didn't see... This is not going to work since you're trying to replace a char by an array of chars with no memory allocation whatsoever.

You need to allocate a new memory chunk (malloc) big enough to hold the new string, then copy the source 's' to the destination, replacing 'c' by 'replace' when needed.

The prototype should be: char *replace_char(char *s, char c, char *replace);

Upvotes: 6

stdcall
stdcall

Reputation: 28880

your replace_char signature returns void

void replace_char (char *s, char find, char replace)

But, when the linker tries to resolve the following

signature = replace_char(signature, "=", '%3B');

It doesn't find any function that's called replace_char and returns int (int is the default if there's no prototype).

Change the replace_char function prototype to match the statement.

EDIT: The warning states that your function returns char, but you use it as a char * also, your function doesn't return anything, do you need to return something ? It looks like you don't really understand the code that you're working with. Fixing errors and warnings without understanding exactly what you need to do is worthless..

Upvotes: 1

Related Questions