Returning a string from function

2019-01-20 17:37发布

I'm trying to make a substring function on c. It must be return "cdef", but it returns nothing. How can i fix it? Thanks.

#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;
}

3条回答
在下西门庆
2楼-- · 2019-01-20 18:21

Your bug is here:

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

The buffer you return becomes invalid as soon as you return from the function.

GCC nicely warns you about this:

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

How can i fix it?

You have to allocate a new buffer (and the caller will have to free it), or have the caller provide output buffer (as Floris suggested).

查看更多
孤傲高冷的网名
3楼-- · 2019-01-20 18:21
#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);
}
查看更多
我想做一个坏孩纸
4楼-- · 2019-01-20 18:24

You are making the mistake of returning a pointer to a variable that may not exist after the function returns. You need to allocate the space in the calling function and just put the result in the space provided, or create permanent space in the function with static. Note - as pointed out by Jonathan Leffler - since the space is "permanent", you can't change the length of the block from one call to the next, and you would have to pick a "sensible" value and test that b-a+1 is not longer than the space allocated. Thus my second method is more robust.

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;
}

As Employed Russian pointed out, using a static in this way is in any case quite dangerous since another piece of code might call this function while you're still using the result of the first call. This is NOT ADVISABLE if you do any kind of multi threading, but it's a quick fix if you have a single thread.

A better formulation is

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

In the latter case, you create space in the calling function and pass the pointer to substring. n your main program you would have

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

As an aside, your method for copying the substring is terribly inefficient. Consider replacing it with

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

From this you can see that you actually need to allocate nText[b-a+1] elements, otherwise there is no space for the final '\0'.

查看更多
登录 后发表回答