1

我在c中写了一个substr函数,我可以在substr函数内部获取返回值,但在main函数中无法获取返回值。以下是所有代码:

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

char* substr(char *source, int start, int length)
{
    char result[10];
    char *r = result;
    strncpy(result, source+start, length);
    printf("substr: %s\n", r);
    return r;
}

int main()
{
    printf("main: %s\n", substr("HELLO", 1, 2));
}

输出是:

substr: EL
main: 

我对c不熟悉,任何人都有解决这个问题的想法,在此先感谢。

4

4 回答 4

4

result仅在调用您的substr. 你指的main是糟糕的记忆。

你可以通过以下方式修复它:

  • 使 substr 中的结果为静态。
  • 动态分配结果(记得释放)
  • 使结果全局化

正如 cthulhu ("Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn" ) 指出的那样:即使您应用了我的修复方法之一:您的字符串也不是 nul 终止的。

此外,由于您有一个固定大小的结果缓冲区,您可能会通过要求一个长度超过 10 的子字符串来引起问题 - 请检查您的参数,或者不使用固定大小的缓冲区。

我还没有测试过这个,所以很可能有一个“偏离”的问题或两个潜伏在角落里......

/* 
 * Caller must free the results if they are non null 
 */
char* substr(char *source, int start, int length)
{
    /* If the input is NULL, return NULL */
    if (source == NULL) return NULL;

    int len = strlen(source);

    /* If the requested start is off the end of the string, return NULL */
    if (start > len) return NULL;

    /* If the requested length is 0 or less, return NULL */ 
    if (length <= 0) return 0;

    char *r = (char*)malloc(length + 1); /* allow space for null terminator */
    if (r != NULL) {
        int i = 0;
        while(source[start] != '\0' && i < length) {
            r[i++] = source[start++];
        }
        r[i] = '\0';
        printf("substr: %s\n", r);
    }
    return r;
}
于 2013-02-25T05:15:27.833 回答
0

如果您希望向调用者返回一个值,那么您应该将存储字符串的位置传递给函数。像 strcpy 这样的标准库函数可以做到这一点。这是一个非常简单的例子。它假设 dest 已经声明并且足够大来存储它。

char * substr(char * dest, char * src, int start, int length)
{
    //  Move substring into passed destination pointer
    strncpy(dest, src + start, length);

    //  Append null to the end to terminate string
    dest[length] = 0;

    //  Return string pointer that can be used in printf and other places
    return dest;
}

int main(int argc, char const *argv[])
{
    char * test = "This is a test.";
    char * dest = malloc(10);
    printf("%s", substr(dest, test, 5, 2));
    free(dest);
    return 0;
}

输出: is

编辑:对于所有返回函数内部 malloc 值的人,如果他们只是在 print 语句中使用它,您如何期望人们释放内存?他们没有收到指向空闲的指针,内存只会挂在那里。

于 2013-02-25T05:42:17.037 回答
0

下面的代码在堆上分配内存。完成后只是free你的记忆。正如其他人指出的那样,strlcpy 总是以 NUL 终止其字符串。

#include <string.h>


char *
substr(char *s, int start, int len)
{
    char *ss;

    if(strlen(s) < start + len)
        return NULL;
    if((ss = malloc(len + 1)) == NULL)
        return NULL;
    strlcpy(ss, s + start, len);
    return ss;
}

int
main(void)
{
    char *s = substr("Hello World!", 6, 5);
    printf("%s\n", s);
    free(s);
    return 0;
}

应该打印World

strlcpy在 Debian Linux 中使用,请使用:

gcc -lcext -o prog prog.c

如果您的操作系统不提供strlcpy,只需将其包含在您的源代码中即可。它是根据 BSD 许可证获得许可的,这意味着可以免费使用、销售等,只要您包含许可证本身。

strlcpy 的实现可以在OpenBSD 的 CVS Web上找到。

于 2013-02-25T05:45:37.053 回答
-1

C中的动态和静态变量

变量声明可以在所有函数之外或在函数内部 所有函数外部的声明都是全局的并且在固定的内存位置静态声明将函数外部的变量声明为“文件全局”(不能被其他源文件中的代码引用) 声明在块语句内{}(函数体或嵌套在函数体内的块语句):动态分配,除非声明为静态当程序执行进入块时分配内存当执行退出块时释放内存如果函数调用自身(直接或间接地),它得到一组新的动态变量(称为堆栈帧)这与对函数的任何其他调用没有区别

您有问题,该变量result[]是已在函数内部分配的变量-其生命周期延伸到函数的整个运行(在堆栈中分配!)因为您需要创建result 动态变量

修复代码:

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

char* substr(char *source, int start, int length)
{
    char* result;
    char *r;
    result=(char*)malloc(sizeof(char)*10);
    r = result;
    strncpy(result, source+start, length);
    printf("substr: %s\n", r);
    return r;
}

int main()
{
    char* r=substr("HELLO", 1, 2);
    printf("main: %s\n",r );
    free(r)//Don't forget to free it!
}

或者你可以result[]像这样制作全局变量:

#include <stdio.h>
#include <string.h>
char result[10];//<======Global
char* substr(char *source, int start, int length)
{
    char *r=result;
    r = result;
    strncpy(result, source+start, length);
    printf("substr: %s\n", r);
    return r;
}

int main()
{
    printf("main: %s\n",substr("HELLO", 1, 2));
}
于 2013-02-25T05:41:23.600 回答