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 notchar *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 likerindex()
, 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;
}
精彩评论