2

C is not a managed language, and it's been a while since I have used an unmanaged language. I need to create a block of code which searches through a character array, and replaces all instances of '2' with 'Ba'. This is quite simple, except for the fact that now the resulting string will be larger than the original, so I need to account for this somehow, and I don't remember how to do this.

Here is try number 4, using pointers:

//Move next 150 characters after replacing all 2 with Ba:
    numberread = read(XYZFile, datatoreadWWW, sizeof(datatoreadWWW));
    int y = strlen(datatoreadWWW); //should be 150.
    int additionallength = y;
    i = 0;
    while(i < y) {
      if(datatoreadWWW[i] == '2') {
        additionallength++; //Since we need to replace any '2' with 'Ba', we should add one character for the a.
      }
      i++;
    }
    //And now use additionallength to create the new char array to be placed in WWW, called newstring:
    char newstring[additionallength];
    int j = 0;
    const char *in = datatoreadWWW;
    char *out = newstring;
    while(*in) {
      if (*in == '2') {
    *out++ = 'B';
    *out++ = 'a';
      }
      else {
    *out++ = *in;
      }
      in++;
    }
    *out++ = '\0';

And I'm still confused/stuck on this, I'm getting garbage values written into the WWW file such as "^Q" and such. Not sure what that means, but it doesn't seem correct.

Edit: The program above seems to be working now. The problem was, if anyone ever reads this post as a resource, that I was adding +1 to additionallength, but this was happening in every iteration, so every so many characters there was an extra empty, null space being put in to the file, which was incorrect. Regardless, I think we've learned that is important to review pointers whenever working in C, as this is the easiest way to accomplish this.

4
  • 1
    "managed" or "unmanaged" has nothing to do with this. I think you are referring to the lack of a standard container with an insert operation. Commented Sep 9, 2014 at 2:16
  • 2
    'Ba' is a multi-byte character constant , it is still a single character after all that. What you actually want is two characters, 'B' and 'a'. As you say, you need to have enough space because the result will be larger than the original. Try writing some code and then posting it. Commented Sep 9, 2014 at 2:18
  • K Matt, hold on I'm working on it! Commented Sep 9, 2014 at 2:20
  • C is a managed language, it's just the developer (rather than the runtime) doing the management :-) Commented Sep 9, 2014 at 2:24

4 Answers 4

2

You can do it like this:

  • Compute the length of the new array by adding the number of '2's to strlen of your string plus one for null terminator
  • Allocate the required number of chars using malloc
  • Go through your string in a loop; if you see '2', add 'B' followed by 'a' to the output;
  • Otherwise, copy the current character to the output.

Note: now that your string is allocated dynamically, you need to call free once you are done using it.

const char* str = ...
int cnt = strlen(str)+1;
for (const char *p = str ; *p ; cnt += (*p++ == '2'))
    ;
char *res = malloc(cnt);
char *out = res;
const char *in = str;
while (*in) {
    if (*in == '2') {
        *out++ = 'B';
        *out++ = 'a';
    } else {
        *out++ = *in;
    }
    in++;
}
*out++ = '\0';

Demo.

Sign up to request clarification or add additional context in comments.

7 Comments

Or, if you don't want to loop over the string twice, you could optimistically pre-allocate a buffer that is only “somewhat” larger than the input and realloc()ate it if it turns out that it was too short.
Can this be accomplished without making any allocation calls? I simply created a new character array with size of the original, plus the amount of 2s that were present, plus 1 for the null terminator.
@Musicode That would work, too, as long as the result is used within the same function. Replace the malloc line with char res[cnt];, and the code would continue to work.
@Musicode You forgot the last line (adding null terminator).
@Musicode Your last attempt is incorrect in other ways, too: you try to use a single index j instead of two pointers in and out in my example. That is why your code skips over some characters, leaving gaps. If you do not like pointers, use indexes; it's all the same. Once the loop is over, put '\0' in the character at your writing index.
|
1

Many of the solutions are excessively complex, pointlessly verbose, and are inefficient (e.g., strlen means three scans when only two are needed).

int newlen = 1;

for (char* p = str; *p; p++)
    newlen += *p == '2' ? 2 : 1;

char newstr[newlen];

for (char *p = str, *q = newstr;; p++)
    if (*p == '2')
    {
        *q++ = 'B';
        *q++ = 'a';
    }
    else if (!(*q++ = *p))
        break;

3 Comments

I tried this method but I am now getting garbage values in my WWW file that I am writing to...
char newstr[newlen]; is not legal C, use char * newstr = malloc(newlen);
@Musicode Perhaps you're writing it incorrectly, or perhaps your input is garbled.. I notice that you're using read ... that's not a good idea and doesn't NUL-terminate the input. Use stdio.
0

Here is an idea how to do this:

  • count the number of '2's in your char array and store in a variable, let's say count.

  • create a new char array, let's say new_word, with the size of your previous char array plus the number of 2's stored in the count variable.

  • iterate from the end of your input word, storing the characters in the new_word. Each time you reach a '2', you insert 'a', then 'B', and of course, update the indexes properly.

Comments

0

You can try like this also..

main()
{
char a[]="abcabcabcabcabcabcabc";
char *p;
int i=0,c=0;

for(i=0;a[i];i++)
if(a[i]=='c')
c++;

printf("c=%d\n",c);
p=calloc(sizeof(a)+c,1);

for(i=0;a[i];i++)
{
static int j=0;
if(a[i]=='c')
    {
    *(p+j++)='n';
    *(p+j++)='s';
    }
 else
    {
    *(p+j++)=a[i];
    }
   }
   printf("%s\n",p);
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.