【问题标题】:Simple C program. String returning from function causes Error简单的 C 程序。从函数返回的字符串导致错误
【发布时间】:2015-06-21 07:51:54
【问题描述】:

以下是 Stephen Kochan 所著的 Programming in C 一书的练习 10.4。它说我应该创建一个函数,从输入字符串派生一部分并将该部分返回给main()(作为字符串,而不是指针)并显示它。 我的代码如下。

#include <stdio.h>

char subString (const char source[], int start, int count, char result[count + 1] ){ //result will be number of characters (count) + 1 (because of null)
int i, j, end = start + count;

// the part excluded must start from i = start and "count" number of characters must be derived and then put on result
for( i = start, j = 0; i < end; ++i, ++j)
    result[j] = source[i];

result[j] = '\0';

return result[count + 1];
}

int main (void){
char result[20] = {0};

const char text1[] = "character";

result[20] = subString( text1, 4, 3, result );
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, result);

return 0;
}

输出是

From "character" this part is being excluded-> "act"

Process returned 0 (0x0)   execution time : 0.332 s
Press any key to continue.

请注意,上面的代码运行良好 - 没有警告。

我无法理解的是当我替换下面的两行时

result[20] = subString( text1, 4, 3, result );
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, result);

用这条线

printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, subString( text1, 4, 3, result ) );

我得到输出:

From "character" this part is being excluded-> "(null)"

Process returned 0 (0x0)   execution time : 0.332 s
Press any key to continue.

这是为什么呢?我怎样才能使用那一行来代替它呢? 另外,我对返回字符串/数组的函数有点困惑。他们往往会导致我犯错误,所以如果有人能给我一些建议,我在与他们合作时应该始终牢记在心,这对我很有帮助。提前谢谢你。

【问题讨论】:

  • 没有名为result[20] 的有效元素。提示:0 基于索引。
  • 您可能需要检查参数并确保 start+count 不会超出源字符串的范围。并且循环应该被去混淆成这样:for(i = 0; i&lt;count; i++) result[i] = source[i+start];
  • @Sourav Ghosh 我用内存中的 20 个位置初始化了字符串并在其中放入了一个 null,因为不久前有人告诉我,当我初始化它们时,我应该总是在其中填充 null 终止符(无论大小),因为这是一种很好的编程习惯。
  • @Lundin 是的,你是对的,这会让事情变得更容易。
  • @RestlessC0bra 请看我的回答。我正在考虑不存在的第 21 个元素。 :-)

标签: c string function pointers return


【解决方案1】:

第 1 点:

在第一种情况下,您使用的是 result 值,该值通过作为参数传递给 subString() 进行了修改。您没有使用subString () 函数的返回值

OTOH,在第二种方法中,您尝试使用subString () 函数的返回值,这也使用了错误的格式说明符。您可以在man page of printf()中了解有关正确格式说明符的更多信息

第 2 点

C 中的数组索引从 0 开始。因此,没有名为result[20] 的有效元素。因此,

result[20] = subString( text1, 4, 3, result );

导致一个错误,进而调用undefined behaviour

【讨论】:

  • ..啊,我明白了(关于第 2 点)。是的,我知道这些。是的,我并不是要把它放在第 21 个元素上。我认为这是键入数组并存储在我想要的字符串中的正确方法。我还在调查这个。我还没有完全理解。是的,第 1 点非常正确,没有意识到这一点。但我仍然想弄清楚如何从函数(而不是指针)返回字符串。还在找。。
  • @RestlessC0bra 是的,请仔细看。始终仔细检查数据类型、返回值和格式说明符。 :-)
  • @RestlessC0bra eturn string from function (and not pointer). 是什么意思? 字符串表示是什么?您可以通过 base address 定位并使用 string,它本身就是一个指针。然后呢?
  • 是的,是的,但我说的是使用字符串术语(严格来说是字符串)而不是使用指针。我知道本质上一个字符串是一个指针。由于这个练习在提出指针之前就在书中,所以它要求我在不使用指针的情况下进行。
  • 是的,我做到了。完美运行。我明白。谢谢大家!
【解决方案2】:
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, subString( text1, 4, 3, result ) );

请注意subString() 返回的字符不是char*,并且您正在使用%s 打印会导致未定义行为的字符。

您的数组正在函数subString() 中被修改,在第一种情况下,您通过返回result[count + 1] 打印数组结果,并且还有一个未定义的行为

result[20] = subString( text1, 4, 3, result );

数组越界访问

你需要修改你的代码

char *subString (const char source[], int start, int count, char result[]){ //result will be number of characters (count) + 1 (because of null)
int i, j, end = start + count;

// the part excluded must start from i = start and "count" number of characters must be derived and then put on result
for( i = start, j = 0; i < end; ++i, ++j)
    result[j] = source[i];

result[j] = '\0';

return result;
}

int main()
{
  // Keep your array here
  char *p = subString( text1, 4, 3, result );
  printf("%s\n",p);
}

void subString (const char source[], int start, int count, char result[]){ //result will be number of characters (count) + 1 (because of null)
    int i, j, end = start + count;

    // the part excluded must start from i = start and "count" number of characters must be derived and then put on result
    for( i = start, j = 0; i < end; ++i, ++j)
        result[j] = source[i];

    result[j] = '\0';

    }

main()

printf("%s\n",result);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 2011-11-19
    • 2016-05-09
    • 2017-09-20
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多