开发者

Handling and writing functions that return strings in c?

I have been struggling with a program that calls functions which return strings. I got some ideas which seemed to work but the program still crashed. Here is part of the code.

printf("CSC 1100       %d           %s       %f          %s\n ",fm_csc_开发者_运维百科1100[i] ,grades(fm_csc_1100[i]),gradepoint(fm_csc_1100[i]),course_comment(gradepoint(fm_csc_1100[i])) );

printf("CSK 1101       %d           %s       %f          %s\n ",fm_csk_1101[i] ,grades(fm_csk_1101[i]),gradepoint(fm_csk_1101[i]),course_comment(gradepoint(fm_csk_1101[i])) );

The program uses a for loop to display marks of students. The marks have been entered in the earlier part of the program. The function calls work fine and it displays the first printf line and then it crashes. The functions which return strings are grades and course_ comment.Here is there code.

char *grades(int z)
{   char *temp3 = "A+";
    char *temp4 = "A";
    char *temp5 = "B+";
    char *temp6 = "B";
    char *temp7 = "C+";
    char *temp8 = "C";
    char *temp9 = "D+";
    char *temp10 = "D";
    char *temp11 = "E";
    char *temp12 = "E-";
    char *temp13 = "F";
     if(z >= 90)
     return temp3;
     else if (z >= 80 && z<=89)
     return temp4;
     else if (z >= 75 && z<=79)
     return temp5;
     else if (z >= 70 && z<=74)
     return temp6;
     else if (z >= 65 && z<=69)
     return temp7;
     else if (z >= 60 && z<=64)
     return temp8;
     else if (z >= 55 && z<=59)
     return temp9;
     else if (z >= 50 && z<=54)
     return temp10;
     else if (z >= 45 && z<=49)
     return temp11;
     else if (z >= 40 && z<=44)
     return temp12;
     else
     return temp13;
     }  

Grades is messy but i had no better way of doing it.

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

Another function i call in the latter parts of the program though it doesnt get there since it crashes is.

char *student_comment(float c)
{ 
   char *temp1 = "Progress";
   char *temp2 ="Stay Put" ;
   if (c > 2.0)
     return temp1;
   else
     return temp2; 
}

All these return strings and the program compiles and runs fine but crashes. How can i handle these functions correctly?


course_comment has no explicit return value in certain conditions. You should never let that happen; instead, return an empty string if there's no other comment to be made. For example:

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

When the function returns without explicitly returning a value, the result is undefined. That usually means your program will crash. (That's actually the best case; the worst case is that it doesn't crash, but gives you unreliable results.)

(By the way, I'm sure you can find better names for your strings than temp, temp1,...temp13, etc.)

EDIT: Originally, I'd written that student_comment has the same issue, but that was a mistake on my part. At least in its current form, it does always return a pointer to a valid string literal. (The way the code was formatted made it harder to trace the logic. I've fixed the formatting.)


Have you given the full definition of the function course_comment()? If so, you have a problem there. What is returned if b >= 2.0?


You forgot to return something when the if conditions are false. e.g.

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

Should probably be

char *course_comment(float b)
{
     if(b < 2.0)
        return "retake"

     return "";
}

Similar for the student_comment() function. If you turn on compiler warnings, the compiler should warn you about this - keep the program free of warnings.


Give this one to your professor:

struct Grade_Range
{
  const char * grade_text;
  unsigned int lower_limit; // inclusive.
  unsigned int upper_limit; // inclusive.
};

static const struct Grade_Range grade_table[] =
{
  {"A+", 90, 100},
  {"A ", 80,  89},
  {"B+", 75,  79},
  {"B ", 70,  74},
  {"C+", 65,  69},
  {"C ", 60,  64},
  {"D+", 55,  59},
  {"D ", 50,  54},
  {"E ", 45,  49},
  {"E-", 40,  44},
  {"F ",  0,  39},
}
static const unsigned int NUM_GRADE_ENTRIES =
    sizeof(grade_table) / sizeof(grade_table[0]);

const char * grades(unsigned int score)
{
  static const char * unknown_score = "Unknown Score";
  const char * result = unknown_score;
  unsigned int index = 0;
  for (index = 0; index < NUM_GRADE_ENTRIES; ++index)
  {
    if ((score >= grade_table[i].lower_limit)
        && (score <= grade_table[i].upper_limit))
    {
       break;
    }
  }
  if (index < NUM_GRADE_ENTRIES)
  {
    score = grade_table[i].grade_text;
  }
  return score;
}

The above technique is known as a table lookup. The function is data driven meaning that the code doesn't change, and the data determines the result. Also, the contents and size of the table can change without having to change the function.

Clean, but may not be the best solution (how ever best is defined). For example, one of the limits may be removed and a binary_search function used. Another alternative is to create an array of 100 character strings and use the score as an index into the array to retrieve the grade. Again, the best solution depends on the restriction: space or execution time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜