1

我正在尝试在 c 上创建一个子字符串函数。它必须返回“cdef”,但它什么也不返回。我该如何解决?谢谢。

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

char* substring( char *, int, int );    

int main(){
    char stuff[] = "abcdefghjklmnoprstuvyz";
    printf("%s\n", stuff);
    printf("%s\n", substring(stuff, 2, 6));

    getch();
    return 0;
}

char* substring(char *text, int a, int b){
    char nText[b-a];
    char tmp[2];
    strcpy(nText, "");
    for(int i=a; i<b; i++){
        tmp[0] = text[i];
        tmp[1] = '\0';
        strcat(nText, tmp);
    }
    return nText;
}
4

3 回答 3

3

您犯了一个错误,即返回一个指向函数返回后可能不存在的变量的指针。您需要在调用函数中分配空间并将结果放在提供的空间中,或者在函数中创建永久空间static。注意——正如 Jonathan Leffler 所指出的——因为空间是“永久的”,你不能将块的长度从一个调用更改为下一个调用,你必须选择一个“合理”的值并测试b-a+1不是比分配的空间长。因此我的第二种方法更健壮。

char* substring(char *text, int a, int b){
    static char nText[100];
    if ((b-a+1)>100) // do something! you can't copy this!
    // code
    return nText;
}

正如 Employed Russian 指出的那样,以这种方式使用静态在任何情况下都是非常危险的,因为另一段代码可能会在您仍在使用第一次调用的结果时调用此函数。如果您执行任何类型的多线程,则不建议这样做,但如果您有单线程,这是一个快速修复。

更好的配方是

void substring(char *text, int a, int b, char *nText) {
    // code, nothing to return
}

在后一种情况下,您在调用函数中创建空间并将指针传递给substring. 在您的主程序中,您将拥有

char shortString[100];
substring(stuff, 4, 6, shortString);
printf("%s\n", shortString);

顺便说一句,您复制子字符串的方法非常低效。考虑将其替换为

for(int i=a; i<b;i++) nText[i-a]=text[i];
nText[b-a] = '\0';

从中可以看出,其实是需要分配nText[b-a+1]元素的,不然finally就没有空间了'\0'

于 2013-04-21T23:49:00.113 回答
1

你的错误在这里:

char* substring(char *text, int a, int b){
    char nText[b-a];
...
    return nText;
}

从函数返回后,返回的缓冲区将变为无效。

GCC 很好地警告你:

t.c:24:5: warning: function returns address of local variable [enabled by default]

我该如何解决?

您必须分配一个新缓冲区(调用者必须释放它),或者让调用者提供输出缓冲区(如 Floris 建议的那样)。

于 2013-04-21T23:47:44.953 回答
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* substring( char *, int, int );    
char* substringb(char *substr, char *text, int a, int b);

int main(){
    char stuff[] = "abcdefghjklmnoprstuvyz";
    char substr[5];
    printf("%s\n", stuff);
    printf("%s\n", substring(stuff, 2, 6));//Things to think to be able to release!
    printf("%s\n", substringb(substr, stuff, 2, 6));

    getch();
    return 0;
}

//dynamic allocate
char* substring(char *text, int a, int b){
    char *nText;
    nText = (char*)malloc((b-a+1)*sizeof(char));
    strncpy(nText, &text[a], b-a);
    ntext[b-a] = 0;
    return nText;
}

//copy to reserve area
char* substringb(char *substr, char *text, int a, int b){
    substr[b-a]=0;
    return strncpy(substr, &text[a], b-a);
}
于 2013-04-21T23:57:16.703 回答