Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何实现字符指针数组函数?_C_Arrays_Pointers - Fatal编程技术网

C 如何实现字符指针数组函数?

C 如何实现字符指针数组函数?,c,arrays,pointers,C,Arrays,Pointers,我尝试编写一个函数,返回一个包含前导字符和尾随字符的字符串副本,这些字符存储在“characters”中,被删除。e、 g strip("-__-ceng_240---__,," , "_-,") return "ceng_240" 这是我的代码,但它不起作用。我想我有一些小问题,但我找不到 char* strip(char* string, char* characters) { int i,j,k=0; char* astring = malloc((str

我尝试编写一个函数,返回一个包含前导字符和尾随字符的字符串副本,这些字符存储在“characters”中,被删除。e、 g

  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;
}
try:char*astring=(char*)malloc(sizeof(char)*(strlen(string)+1))

试试这个:

#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;
}
#包括
#包括
#包括
字符*条带(字符*字符串,字符*字符){
int i,j,k;
char*p=string+strspn(string,characters);//跳过前面
char*astring=malloc(strlen(p)+1);
对于(j=i=0;p[i]!='\0';i++){
astring[j++]=p[i];//复制
}
astring[j]='\0';
对于(k=j-1;k>=0;--k){//从尾部删除
if(strchr(字符,astring[k]))
astring[k]='\0';
其他的
打破
}
astring=realloc(astring,strlen(astring)+1);//需要+1
回程收缩;
}
内部主(空){
char*result=strip(“-\uuuuuuuuu-ceng\u240-\uuuuuu,,,”,“,”);
printf(“%s”\n”,结果);
自由(结果);
返回0;
}

这里的逻辑有争议。。。使用列表中唯一的
字符和
strlen(字符)>1
时,代码将始终将所有传递的
字符串
复制到
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
。以下是一个改动最小的修复程序:

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;
}
在这个函数中,我们仍然需要做一些事情,以使其健壮

使用动态内存分配时要做的一件重要事情是检查
malloc
realloc
的结果,并在内存不足时退出

为了节省时间,您可能希望去掉
realloc
。一种方法是进行两次传递,或者如果您不太关心内存,您可以
calloc
并删除
realloc
astring[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;
}
char*strip(char*src,char chars[],char dest[]
{
char*c;
while(*src){
c=字符;
而(*c&&*c!=*src)
++c;
如果(*c)
++src;
其他的
打破
}
char*x=src+strlen(src);
而(src您也可以使用strspn()找到有效的起始点,然后反转剩余的字符串(放入临时缓冲区),然后再次使用strspn()找到位置。
使用这两个结果,您可以使用strndup()将正确的范围从源字符串复制到新内存中。

这不是最有效的方法,而是一种方法;-)

我称之为修剪==向左修剪&向右修剪 与此工作示例类似:

#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"
}
#包括
char*trim_左(char*s,char*p){
char*q;
而(*s){
q=p;
while(*q){
if(*s!=*q)q++;else{s++;break;}
}
如果(!*q)中断;
}
返回s;
}
char*trim_right(char*s,char*p){
char*r=s;
char*q;
而(*s)s++;
s--;
而(s!=r){
q=p;
while(*q){
if(*s!=*q)q++;else{s--;break;}
}
如果(!*q)中断;
}
s++;
*s=0;
返回r;
}
char*trim(char*s,char*p){
返回左微调(右微调)(s、p、p);
}
int main(){
字符str[]=“-uuuuu-曾uu 240-uuuuu,”;
char*p=trim(str,“-”);
printf(“%s”,p);//ceng_240
//返回“曾古240”
}
使用辅助函数的另一种方法是\u 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"
}
#包括
字符修剪_chars[]=“-,”;
int是_trimchar(char c){
char*p=trim_chars;
做{
如果(*p==c),则返回1;
p++;
}而(*p);
返回0;
}
char*trim_左(char*s){
而(*s)
if(is_trimchar(*s))s++;else break;
返回s;
}
char*trim_right(char*s){
char*r=s;
而(*s)s++;
s--;
而(s!=r)
if(is_trimchar(*s))s--;else中断;
s++;
*s=0;
返回r;
}
char*trim(char*s){
返回左微调(右微调);
}
int main(){
字符str[]=“-uuuuu-曾uu 240-uuuuu,”;
char*p=修剪(str);
printf(“%s”,p);//ceng_240
//返回“曾古240”
}

Debugger………逻辑严重中断。请尝试先提出一个设计,然后对其进行编码。此外,不要在前面
malloc
一个过大的字符串,然后收缩它。相反,您只需要找到开始和停止索引。然后您可以
malloc
所需的确切长度,并复制所需的端口将字符串初始化为它。你不应该像这样调用realloc。如果由于某种原因失败,你已经丢失了指向原始内存块的指针。你的realloc太短了。如果可以的话,请对你的答案提供一点解释。请注意,在直C中…不需要或不建议强制转换malloc()的输出…请注意,此实现确实会损坏输入字符串--这可能是正确的做法,也可能不是正确的做法。