문제

I'm having trouble replacing a whole word in a sentence.

For example:

Replace:

  • the to a
  • hello to hi
  • house to tree

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.?

도움이 되었습니까?

해결책 3

#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.
*/

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top