开发者

Deleting characters from C string

开发者 https://www.devze.com 2023-04-10 20:24 出处:网络
Given a string (as the argument to function), after a given combination of characters, I need to delete the sequence of zeros, if exits(it only necessarily to modify the string). For example, if the c

Given a string (as the argument to function), after a given combination of characters, I need to delete the sequence of zeros, if exits(it only necessarily to modify the string). For example, if the combination of characters is x+, the string 20.301x+000005 must be converted to 20.301x+5.

I tried this:

void convertStr(char *analysisBuffer)
{
    char *exp;

    if( (exp = strstr(analysisBuffer,"x+"))!=NULL||(exp = strstr(analysisBuffer,"X+"))!= NULL)
    {
        exp += 2;
        char * zeroIt = exp;
      开发者_如何学编程  while(*zeroIt == '0')
            ++zeroIt;
        unsigned int x = exp - analysisBuffer;
        analysisBuffer[x] = '\0';
        strcat(analysisBuffer,zeroIt);
    }
}

Can anyone advise me how to implement it correctly?


This is a version that works for multiple occurences of the expression and reduces the size of the string so that no memory is occupied by zero terminators. This is probably slower and completely unnecessary but gives you the awesome feeling of doing something fancy.

Disclaimer: I haven't written any pure C in a long while.

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

char* strip_zero(char* str, const char* startseq) {
  // while there is an occurence of the substring
  size_t ssize = strlen(startseq);
  size_t oldlen = strlen(str) + 1; // account for terminator
  size_t rems = 0;
  char* begin = str;

  while((begin = strstr(begin, startseq))) {
    // move to the end of the sequence
    begin += ssize;
    char* walk = begin;
    // walk until we reach nonzero
    while(*walk == '0') { ++walk; ++rems; }
    // move the string forward
    memmove(begin, walk, strlen(walk) + 1);
  }

  // realloc the string
  return (char*)realloc(str, oldlen - rems);
}

int main(void)
{
  // make a copy so we can modify
  const char* a = "x+20.301x+00000x+0005x+";
  char* foo = (char*)malloc(strlen(a) + 1);
  strcpy(foo, a);
  printf("%s \n", foo);
  foo = strip_zero(foo, "x+");
  printf("%s \n", foo);
  free(foo);
  return 0;
}


Below is a more complete example of what you want. I tried to improve on a few items:

  • Use the strcasestr function for a case insensitive test. (We need the #define _GNU_SOURCE for this)
  • Use strcat (as you did) to append the tail of the string to the head.
  • Be careful to define the string as char test[] = "..." and not char *test = "...", as the latter will segfault.
  • There is an 'if' to see if we have to skip one ore more '0'.
  • You can get rid of the while loop, using a function like rindex(), which gives the right most index of a character in a string.

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

    void
convertStr(char *analysisBuffer)
{
    char *exp = strcasestr(analysisBuffer, "x+");

    if (exp) {
        exp += 2;
        if (*exp == '0') {
            while (*exp == '0') {
                *exp = '\0';
                exp++;
            }
            strcat(analysisBuffer, exp);
        }
    }
}

    int
main(int argc, char *argv[])
{
    char test[] = "20.301X+0005";

    printf("before: %s\n", test);
    convertStr(test);
    printf("after : %s\n", test);

    return EXIT_SUCCESS;
}


Something like

char * write = str;
char * read = str;
while(*read){
    while(*read && *read == '0'){ read++; }
    *write++ = *read++;
}
*write = '\0';

? (this is untested)


Instead of:

   unsigned int x = exp - analysisBuffer;
   analysisBuffer[x] = '\0';
   strcat(analysisBuffer,zeroIt);

you could just do:

   memmove(exp, zeroIt, strlen(zeroIt) + 1);


size_t strip0( char *buff);
size_t strip0( char *buff)
{
size_t src,dst;

for (src=dst=0; buff[dst] = buff[src++] ;dst++ ) {
   if ((buff[dst] == 'x' || buff[dst] == 'X') && buff[src] == '+') {
      buff[++dst] = buff[src++] ;
      while (buff[src] == '0') src++;
      }
   }
return dst;
}

#include <stdio.h>

int main(int arc, char **argv)
{
char data[] = "100x+003 aap 200x+300 100X+003 noot 200X+300 mies 1234xX+000000000zzz";

printf("Org: %s\n", data);
strip0(data);
printf("New: %s\n", data);

return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消