#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct pair {
char *key;
char *value;
} Pair;
int cmp(const void *a, const void *b){
return strcmp(((const Pair*)a)->key, ((const Pair*)b)->key);
}
char *dictionary(const char *word){
static const Pair table[] =
{{"hello", "hi"}, {"house", "tree"},{"the", "a"}};
char *p, *wk = strdup(word);
Pair key, *pair;
for(p=wk;*p;++p)
*p = tolower(*p);
key.key = wk;
pair=bsearch(&key, table, sizeof(table)/sizeof(Pair), sizeof(Pair), cmp);
free(wk);
if(pair){
wk=strdup(pair->value);
if(isupper(*word))
*wk = toupper(*wk);//capitalize
return wk;
}
return NULL;
}
typedef char Type;
typedef struct vector {
size_t size;
size_t capacity;
Type *array;
} Vector;
Vector *vec_make(){
Vector *v;
v = (Vector*)malloc(sizeof(Vector));
if(v){
v->size = 0;
v->capacity=16;
v->array=(Type*)realloc(NULL, sizeof(Type)*(v->capacity += 16));
}
return v;
}
void vec_add(Vector *v, Type value){
v->array[v->size] = value;
if(++v->size == v->capacity){
v->array=(Type*)realloc(v->array, sizeof(Type)*(v->capacity += 16));
if(!v->array){
perror("memory not enough");
exit(-1);
}
}
}
void vec_adds(Vector *v, Type *values, size_t size){
while(size--)
vec_add(v, *values++);
}
char *convert(const char *str){
static const char *delimiters = " \t\n,.!?";
char *in = strdup(str);
char *out;
char *inp = in;
Vector *v = vec_make();
while(*inp){
size_t size;
if(size = strcspn(inp, delimiters)){
char *word, *cnv_word;
word = malloc(size+1);
memcpy(word, inp, size);
word[size]='\0';
if(NULL==(cnv_word = dictionary(word)))
vec_adds(v, word, size);
else
for(out = cnv_word; *out; ++out)
vec_add(v, *out);
free(word);
free(cnv_word);
inp += size;
}
if(size = strspn(inp, delimiters)){
vec_adds(v, inp, size);
inp += size;
}
}
vec_add(v, '\0');
out = v->array;
free(v);
free(in);
return out;
}
int main(void){
char input[] = "Hello there, this is the house.";
char *output = convert(input);
puts(input);
puts(output);
free(output);
return 0;
}
/* result
Hello there, this is the house.
Hi there, this is a tree.
*/
Pure C string-replace for a whole word
Pregunta
I'm having trouble replacing a whole word in a sentence.
For example:
Replace:
the
toa
hello
tohi
house
totree
Input:
Hello there, this is the house.
Output:
Hi there, this is a tree.
Is it possible to do it only with the <string.h>
library, with no Regex etc.?
Solución 3
Otros consejos
May be this can help you str-replace-c
It's entirely possible, but the standard library doesn't have any function to support it directly. Therefore, to do it, you'd typically use something like strstr
to find the existing instance(s) of the string you want to replace, memmove
to move the rest of the string, an overwrite the original with the desired replacement either manually, or perhaps with strncpy
.
Note that in this case, your replacement strings are all shorter than the original they're replacing. This implies that the replacements can always be done safely. If the replacement is longer than the original, you'll also have to do something to track the maximum string length, and ensure you don't exceed it.
Oh, one other not-so-minor point, but if you're searching for something as a complete word, not just an occurrence of that string inside another word, you probably want to search for <space>word<space>
, except at the beginning or end of the string, so (for example) you wouldn't replace the
in there
with a
and turn the first word from there
to are
.
create a hash of before and after, ie what you are searching for and what you want to replace with, iterate through the string and search for the words with something like KMP or rabin karp and find what you need in your hash table.