C 如何实现字符指针数组函数?
我尝试编写一个函数,返回一个包含前导字符和尾随字符的字符串副本,这些字符存储在“characters”中,被删除。e、 gC 如何实现字符指针数组函数?,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
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()的输出…请注意,此实现确实会损坏输入字符串--这可能是正确的做法,也可能不是正确的做法。