2013-02-25 92 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