2013-02-25 59 views
1

我写在C SUBSTR功能,我可以得到SUBSTR函数中的返回值,但不能得到在主函数返回值。下面是全部代码:我写在C SUBSTR功能,但主要的功能不能得到返回值

#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,任何人的想法,提前解决这个问题,谢谢。

+0

可能的重复[返回的字符串值变成垃圾](http://stackoverflow.com/questions/15020105/returned-string-value-becomes-garbage) – alk 2013-02-25 05:58:27

回答

4

result来电转接到您substr过程中只存在。 您的main引用了错误的内存。

您可以通过修复:

  • 使得结果SUBSTR静态的。
  • 动态分配结果(记得要释放)
  • 使结果全球

至于邪神( “Ph'nglui mglw'nafh邪神拉莱耶wgah'nagl fhtagn”)指出:即使你申请我的一个修补程序:你的字符串没有被终止。

而且因为你有一个固定大小的结果缓冲区,你可以问一个子字符串比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; 
} 
+1

此外,该字符串不以null结尾。 – 2013-02-25 05:21:22

+0

它适合我,非常感谢! – ecco 2013-02-25 06:32:56

-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)); 
} 
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分配,你希望人们如何释放内存,如果他们只是用它在打印语句?他们没有收到指向空闲的指针,内存只会留在那里。

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

要在Debian的Linux上使用strlcpy使用:

gcc -lcext -o prog prog.c 

如果您的操作系统没有提供strlcpy只是包括它自己在你的来源。它是根据BSD许可证颁发的,这意味着可以免费使用,出售等,只要您包含许可证本身即可。

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

+0

strlcpy不在标准中。据我所知,没有Windows端口,因为它不能在Windows下的gcc编译。这不是跨平台代码或直接打印的最佳解决方案。 – ozdrgnaDiies 2013-02-25 05:55:27

+0

@ozdrgnaDiies感谢您的评论,我相应地更新了我的答案。 – emil 2013-02-25 07:17:05