将char添加到C中的char *?

时间:2012-07-04 19:54:26

标签: c string char append

我正在尝试创建一个快速函数,通过其数字在字符串中获取单词/参数:

char* arg(char* S, int Num) {
    char* Return = "";
    int Spaces = 0;
    int i = 0;
    for (i; i<strlen(S); i++) {
        if (S[i] == ' ') {
            Spaces++;
        }
        else if (Spaces == Num) {
            //Want to append S[i] to Return here.
        }
        else if (Spaces > Num) {
            return Return;
        }
    }
    printf("%s-\n", Return);
    return Return;
}

我找不到将字符放入Return的方法。我发现很多帖子提示strcat()或带有指针的技巧,但每一个都是段错误。我也看到人们说应该使用malloc(),但我不确定我是如何在这样的循环中使用它的。

5 个答案:

答案 0 :(得分:2)

我不会理解你要做的是什么,但你的代码有两个问题:

  • 您正在为Return分配一个只读字符串;那个字符串将在你的 二进制数据部分,它是只读的,如果你尝试修改它,你会得到一个段错误。
  • 你的for循环是O(n ^ 2),因为strlen()是O(n)

解决“如何返回字符串”问题有几种不同的方法。例如,您可以:

  • 使用malloc() / calloc()分配新字符串,如建议
  • 使用asprintf(),它类似,但如果需要,可为您提供格式
  • 将输出字符串(及其最大大小)作为参数传递给函数

前两个要求调用函数free()返回值。第三个允许调用者决定如何分配字符串(堆栈或堆),但需要某种关于输出字符串所需的最小大小的契约。

答案 1 :(得分:1)

在您的代码中,当函数返回时,Return也将消失,因此这种行为是未定义的。它可能有用,但你从不依赖它。

通常在C中,您希望将“return”字符串作为参数传递,这样您就不必始终free。两者都需要调用方的本地变量,但是malloc它将需要额外的调用来释放分配的内存,并且比将指针传递给局部变量更昂贵。

至于附加到字符串,只需使用数组表示法(跟踪当前的char / index),不要忘记在末尾添加空字符。

示例:

int arg(char* ptr, char* S, int Num) {
    int i, Spaces = 0, cur = 0;
    for (i=0; i<strlen(S); i++) {
        if (S[i] == ' ') {
            Spaces++;
        }
        else if (Spaces == Num) {
            ptr[cur++] = S[i]; // append char
        }
        else if (Spaces > Num) {
            ptr[cur] = '\0';   // insert null char
            return 0;          // returns 0 on success
        }
    }

    ptr[cur] = '\0';           // insert null char
    return (cur > 0 ? 0 : -1); // returns 0 on success, -1 on error
}

然后像这样调用它:

char myArg[50];
if (arg(myArg, "this is an example", 3) == 0) {
    printf("arg is %s\n", myArg);
} else {
    // arg not found
}

请确保您没有溢出ptr(例如:通过传递其大小并在函数中添加检查)。

您可以通过多种方式改进代码,但我们首先要让它符合标准。 ; - )

P.S。:除非需要,否则不要malloc。在那种情况下,你没有。

答案 2 :(得分:0)

char * Return;   //by the way horrible name for a variable.
Return = malloc(<some size>);
......
......
*(Return + index) = *(S+i); 

答案 3 :(得分:0)

您无法为字符串文字指定任何内容,例如“”。

您可能希望使用循环来确定字符串中您要查找的单词开头的偏移量。然后通过继续穿过字符串找到它的长度,直到遇到结束或另一个空格。然后,你可以malloc一个大小等于offset + 1大小的字符数组(对于null终止符。)最后,将子字符串复制到这个新缓冲区并返回它。

另外,如上所述,你可能想要从循环中删除strlen调用 - 大多数编译器会优化它,但它确实是数组中每个字符的线性操作,使得循环O(n ** 2 )。

答案 4 :(得分:0)

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

char *arg(const char *S, unsigned int Num) {
    char *Return = "";
    const char *top, *p;
    unsigned int Spaces = 0;
    int i = 0;

    Return=(char*)malloc(sizeof(char));
    *Return = '\0';
    if(S == NULL || *S=='\0') return Return;
    p=top=S;
    while(Spaces != Num){
        if(NULL!=(p=strchr(top, ' '))){
            ++Spaces;
            top=++p;
        } else {
            break;
        }
    }
    if(Spaces < Num) return Return;
    if(NULL!=(p=strchr(top, ' '))){
        int len = p - top;
        Return=(char*)realloc(Return, sizeof(char)*(len+1));
        strncpy(Return, top, len);
        Return[len]='\0';
    } else {
        free(Return);
        Return=strdup(top);
    }
    //printf("%s-\n", Return);
    return Return;
}

int main(){
    char *word;

    word=arg("make a quick function", 2);//quick
    printf("\"%s\"\n", word);

    free(word);
    return 0;
}