如何在C语言中编写一个返回字符串的函数?

3

当我尝试使用printf(" %s",course_comment(1.0) );调用我的函数时,程序会崩溃。这是我的函数:

char *course_comment(float b) 
{ 
   if(b < 2.0) 
     return("Retake"); 
}

为什么它会崩溃?我该如何修复它?


如果这真的是整个函数,那么如果 b >= 2.0,你就没有返回任何东西(这不是你特别的问题,但在某些时候它会成为一个问题)。 - Michael Mrozek
如果我添加一个缺失的括号,它对我来说可以正常工作。出了什么问题? - Fred Foo
当谈论 C 语言时,“它不起作用”是相当广泛的。请更具体 :) - Aiden Bell
如何在我的C代码中返回一个字符串?可能是重复问题,我认为还会有很多类似的问题。 - Aiden Bell
显示剩余2条评论
7个回答

4
如果您的字符串是常量且没有意图修改结果,则使用字符串字面值是最好的选择,例如:
```html

如果您的字符串是常量且没有意图修改结果,则使用字符串字面值是最好的选择,例如:

```
#include <stdio.h>

static const char RETAKE_STR[] = "Retake";
static const char DONT_RETAKE_STR[] = "Don't retake";

const char *
course_comment (float b)
{
  return b < 2.0 ? RETAKE_STR : DONT_RETAKE_STR;
}

int main()
{
  printf ("%s or... %s?\n",
      course_comment (1.0), 
      course_comment (3.0));
  return 0;
}

否则,您可以使用 strdup 克隆字符串 (不要忘记使用 free 释放它):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *
course_comment (float b)
{
  char result[256];

  if (b < 2.0)
    {
      snprintf (result, sizeof (result), "Retake %f", b);
    }
  else
    {
      snprintf (result, sizeof (result), "Do not retake %f", b);
    }
  return strdup (result);
}

int main()
{
  char *comment;

  comment = course_comment (1.0);
  printf ("Result: %s\n", comment);
  free (comment); // Don't forget to free the memory!

  comment = course_comment (3.0);
  printf ("Result: %s\n", comment);
  free (comment); // Don't forget to free the memory!

  return 0;
}

3
根据您程序的顺序/结构,当“course_comment”首次调用时,它可能未声明并且C将默认其返回类型为“int”。编译时请检查编译器警告。同时确保您了解函数原型及其使用的时间和位置(基本上应该在任何地方使用)。我认为1.0上缺少的“f”意味着参数将自动转换为int类型。这个方法是可行的,但我不会这样做。
#include <stdio.h>

const char *course_comment(float b); // <- fn prototype


int main(int argc, char *argv[]) {

    printf(" %s",course_comment(1.0f));


}


const char *course_comment(float b) 
{ 
   if(b < 2.0) 
     return("Retake"); 
}

2

建议返回一个const char *的文字,因为它们无法被修改。

如果b不小于2.0,您的函数会返回什么? 如果您尝试使用返回值会发生什么? 是您的确切代码导致了崩溃吗?


他正在调用它并传递了 1.0,所以这不是问题。 - Michael Mrozek

1

返回这样的指针并不是特别美观的。你能做的最好的事情就是像这样:

main.c

#include "some_other_file.h"

int main()
{
  printf(" %s", course_comment(1.0f) );
  return 0;
}

some_other_file.h

#ifndef YADA_YADA_H
#define YADA_YADA_H 

const char* course_comment(float b);

#endif

some_other_file.c

static const char COMMENT_RETAKE [] = "Retake";



const char* course_comment(float b) 
{ 
  const char* result;


  if(b < 2.0f)
  {
    result = COMMENT_RETAKE;
  }
  else
  {
    result = ""; /* empty string */
  }

  return result;
}

请注意,在处理浮点数时应使用1.0f表示法,在处理双精度浮点数时应使用1.0表示法。否则,编译器将会将您的变量隐式提升为双精度浮点数,使代码运行变慢。

1

看这个答案

如其他人所说,加上一个else语句并返回一些值...请告诉我们错误的确切信息!

我的两分钱


1

因为1.0不返回任何内容,所以您得到了一个NULL指针。

不是您的函数崩溃了,而是printf崩溃了:

printf(" %s", NULL);

经验法则:

  • 始终具有定义的返回值
  • gcc -Wall会显示所有警告

1
但是但是但是...1.0 < 2.0 是TRUE,所以它应该返回。问题在哪里?我同意它需要另一条路径来处理其他的返回,但当b < 2.0时,那个函数的逻辑有什么问题吗? - jcolebrand
这是不正确的。1.0 < 2.0?请参考其他答案。 - David Victor
在Linux上,printf("%s",NULL);不会崩溃,但会输出(null) - Basile Starynkevitch

0
如果你想返回一个字符串字面量,例如return "blah",那么返回类型应该是const char*

它不需要这样,但它应该这样。它不会引起这个问题。 - Michael Mrozek
这并不是严格的情况。在 C 中将字符串字面量放置于 char * 是合法的;只是你不能对其进行写入操作。 - bdonlan
我同意这并不是必须的,但不这样做只会带来麻烦。 - Eric Fortin
修正答案以删除需要。 - Eric Fortin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接