如何实现字符指针数组功能?

时间:2016-05-19 19:53:32

标签: c arrays pointers

我尝试编写一个函数,该函数返回带有前导和尾随字符的字符串副本,这些字符存储在"字符"中,已删除。例如

  strip("-__-ceng_240---__,," , "_-,") 

  return "ceng_240"

这是我的代码,但它不起作用。我想我没有什么问题,但我找不到它们。

char* strip(char* string, char* characters) {

    int i,j,k=0;

    char* astring = malloc((strlen(string)+1));

    for(i=0;string[i]!='\0';i++) {
        for(j=0;characters[j]!='\0';j++) {
            if(string[i]==characters[j])
                continue;
            else if(string[i]!=characters[j]) {
                astring[k] = string[i];
                k++;
                break;
            }
        }
    }
    astring[k] = '\0';
    astring = realloc(astring,strlen(astring));

    return astring;
}

5 个答案:

答案 0 :(得分:1)

我称这个修剪==修剪左边&修剪正确 像这个工作样本:

#include <stdio.h> 

char* trim_left(char* s, char* p) {
    char*q;
    while (*s){
        q = p;
        while (*q){
            if (*s != *q)q++; else { s++; break; }
        }
        if (!*q)break;
    }
    return s;
}
char* trim_right(char* s, char* p) {
    char *r = s;
    char*q;
    while (*s) s++;
    s--;
    while (s != r){
        q = p;
        while (*q){
            if (*s != *q)q++; else { s--; break; }
        }
        if (!*q)break;
    }
    s++;
    *s = 0;
    return r;
}
char* trim(char* s, char* p) {
    return  trim_left(trim_right(s, p), p);
}

int main(){
    char str[] = "-__-ceng_240---__,,";
    char *p = trim(str, "_-,");
    printf("%s", p); //ceng_240
    //return "ceng_240"
}

另一种方式使用辅助函数is_trimchar:

#include <stdio.h> 

char trim_chars[] = "_-,";

int is_trimchar(char c){
    char *p = trim_chars;
    do{
        if (*p == c)return 1;
        p++;
    } while (*p);
    return 0;
}


char* trim_left(char* s) {
    while (*s)
        if (is_trimchar(*s)) s++; else break;
    return s;
}

char* trim_right(char* s) {
    char *r = s;
    while (*s) s++;
    s--;
    while (s != r)
        if (is_trimchar(*s)) s--; else break;
    s++;
    *s = 0;
    return r;
}

char* trim(char* s) {
    return  trim_left(trim_right(s));
}

int main(){
    char str[] = "-__-ceng_240---__,,";
    char *p = trim(str);
    printf("%s", p); //ceng_240
    //return "ceng_240"
}

答案 1 :(得分:0)

尝试:char * astring =(char *)malloc(sizeof(char)*(strlen(string)+1));

答案 2 :(得分:0)

试试这个:

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

char* strip(char* string, char* characters) {
    int i, j, k;
    char *p = string + strspn(string, characters);//skip front
    char *astring = malloc(strlen(p)+1);

    for(j=i=0; p[i] != '\0'; i++) {
        astring[j++] = p[i];//copy
    }
    astring[j] = '\0';
    for(k = j -1; k >= 0; --k){//delete from tail
        if(strchr(characters, astring[k]))
            astring[k] = '\0';
        else
            break;
    }
    astring = realloc(astring, strlen(astring) + 1);//need +1
    return astring;
}
int main(void){
    char *result = strip("-__-ceng_240---__,," , "_-,");
    printf("'%s'\n", result);
    free(result);
    return 0;
}

答案 3 :(得分:0)

此处的逻辑存在争议......列表中包含唯一的charactersstrlen(characters) > 1代码将始终将所有传递的string复制到astring。这里有一对printf嵌入到原始代码中,将说明:

char* strip(char* string, char* characters) {

    int i,j,k=0;

    char* astring = malloc((strlen(string)+1));

    for(i=0;string[i]!='\0';i++) {
        for(j=0;characters[j]!='\0';j++) {
            if(string[i]==characters[j])
                continue;
            else if(string[i]!=characters[j]) {
                printf("string[%d],characters[%d]: %c,%c\n",
                        i, j, string[i], characters[j]);
                astring[k] = string[i];
                k++;
                printf("astring: %s\n", astring);
                break;
            }
        }
    }
    astring[k] = '\0';
    astring = realloc(astring,strlen(astring));

    return astring;
}

输出是:

string[0],characters[0]: -,_
astring: -
string[1],characters[1]: _,-
astring: -_
string[2],characters[1]: _,-
astring: -__
string[3],characters[0]: -,_
astring: -__-
string[4],characters[0]: c,_
astring: -__-c
string[5],characters[0]: e,_
astring: -__-ce
string[6],characters[0]: n,_
astring: -__-cen
string[7],characters[0]: g,_
astring: -__-ceng
string[8],characters[1]: _,-
astring: -__-ceng_
string[9],characters[0]: 2,_
astring: -__-ceng_2
string[10],characters[0]: 4,_
astring: -__-ceng_24
string[11],characters[0]: 0,_
astring: -__-ceng_240
string[12],characters[0]: -,_
astring: -__-ceng_240-
string[13],characters[0]: -,_
astring: -__-ceng_240--
string[14],characters[0]: -,_
astring: -__-ceng_240---
string[15],characters[1]: _,-
astring: -__-ceng_240---_
string[16],characters[1]: _,-
astring: -__-ceng_240---__
string[17],characters[0]: ,,_
astring: -__-ceng_240---__,
string[18],characters[0]: ,,_
astring: -__-ceng_240---__,,
-__-ceng_240---__,,

仅当所有 astring不匹配时,才构建逻辑以复制到characters。这是一个修改很少的修复:

char* strip(char* string, char* characters) {

    int i,j,k=0;

    char* astring = malloc((strlen(string)+1));

    for(i=0;string[i]!='\0';i++) {
        for(j=0;characters[j]!='\0';j++)
            if(string[i]==characters[j])
                break;
        if(characters[j])
            continue;
        astring[k] = string[i];
        k++;
    }
    astring[k] = '\0';
    astring = realloc(astring,strlen(astring));

    return astring;
}

我们还需要在此功能中执行一些操作才能使其健壮...

使用动态内存分配时要做的一件重要事情是检查mallocrealloc的结果,并在内存不足时保释。

为了节省时间,您可能想要摆脱realloc。一种方法是做两次通过,或者如果你不太关心记忆,你可以calloc并放弃reallocastring[k] = '\0'

像我这样使用malloc似乎是一个等待发生的内存泄漏。所以,更好的是,如果你可以通过引用传递结果并将关于如何处理内存的决定交给调用者 - 那么调用者可以在堆栈上分配或做任何它喜欢的事情。

请注意,结果也会删除字符串中间的“_”....如果这不是你想要的,这里是考虑到以上所有内容的我的版本:

char *strip(char *src, char chars[], char dest[])
{
        char *c;
        while (*src) {
            c=chars;
            while (*c && *c!=*src)
                ++c;
            if (*c)
                ++src;
            else
                break;
        }
        char *x = src + strlen(src);
        while (src <= --x) {
            c=chars;
            while (*c && *c!=*x)
                ++c;
            if (!*c)
                break;
        }
        size_t n = x - src + 1;
        strncpy(dest, src, n);
        dest[n]='\0';
        return dest;
}

答案 4 :(得分:0)

您还可以使用strspn()查找有效的起始点,然后将剩余的字符串反转(进入临时缓冲区)并再次使用strspn()查找位置。 使用两个结果,您可以使用strndup()将源字符串中的正确范围复制到新内存中。 它不是最有效的方式,而是它的方式; - )