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でないことをテストする必要があります割り当てられたスペースよりも長くなります。したがって、私の 2 番目の方法はより堅牢です。

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

雇用されたロシア人が指摘したように、この方法で static を使用することは、最初の呼び出しの結果をまだ使用している間に別のコードがこの関数を呼び出す可能性があるため、いずれにしても非常に危険です。マルチスレッドを使用する場合、これはお勧めできませんが、シングル スレッドの場合は簡単に修正できます。

より良い定式化は

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]これから、実際に要素を割り当てる必要があることがわかります。そうしないと、 final のためのスペースがありません'\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 に答える