【问题标题】:C:Function not returning correct valueC:函数没有返回正确的值
【发布时间】:2015-12-27 00:32:19
【问题描述】:

这个程序的目的是打印尽可能多的输入文本(直到数组限制),但它应该显式返回输入文本的确切长度(数值)。

下面是我的代码:

#include <stdio.h>
#define MAXLINE 1000

int line_input(char array[], int maxlinelimit);
void copy(char toarray[], char fromarray[]);

int line_input(char s[], int limit)
{
    char ch;
    int i = 0;
    for(; ((ch = getchar()) != EOF) && (ch != '\n'); ++i)
    {
        s[i] = ch;
    }
    if(ch == '\n')
    {
        s[i] = ch;
        ++i;
    }
    s[i] = '\0';
    printf("%d\n", i);
    return i;
}

void copy(char to[], char from[])
{
    int i;

    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

int main()
{
    int length;
    length = 0;
    int max;
    max = 0;
    char line[MAXLINE], longest[MAXLINE];
    while((length = line_input(line, MAXLINE) > 0))
    {
        printf("%d\n%s\n", length, line);
        if(length > max)
        {
            max = length;
            copy(longest, line);
        }

    }
    if(max > 0)
    {
        printf("\n\n%d is the size of the longest line\n", max);
        printf("%s\n\n", longest);
    }
    return 0;
}

您会发现名为“line_input()”的用户定义函数由于某些我不知道的原因没有返回它应该返回的值。我认为没有任何警告是我没有希望解决的。

看看能不能解决。

P.S. - 输入文本是键盘上的任何字符串。不过,按“Enter”将开始一个新行。

【问题讨论】:

  • 不使用参数limit 很奇怪。顺便说一句,我建议您首先将(length = line_input(line, MAXLINE) &gt; 0) 更改为(length = line_input(line, MAXLINE)) &gt; 0,并让系统将返回值本身保存到length
  • “...没有返回应得的值...”不如说明 1) 它返回的值 2) 预期的值 3) 输入那样有用。

标签: c arrays function return-value return-type


【解决方案1】:
  • 你必须使用int,它可以安全地存储所有(不是多字节)字符和EOF,来存储getchar()的结果。
  • 您必须限制要保存的长度以避免缓冲区溢出。
  • 停止计算换行符以使返回值更准确。

试试这个:

int line_input(char s[], int limit)
{
    int ch;
    int i = 0, index = 0;
    for(; ((ch = getchar()) != EOF) && (ch != '\n'); ++i)
    {
        if (index < limit - 1) s[index++] = ch;
    }
    if(ch == '\n')
    {
        if (index < limit - 1) s[index++] = ch;
    }
    s[index] = '\0';
    printf("%d\n", i);
    return i;
}

还要注意limitiindex的类型和返回值应该是size_t,因为它们是处理大小的。

更新:另一个版本,它可以从输入末尾分辨出空白行,并进行了一些改进

#include <stdio.h>
#define MAXLINE 1000

int line_input(char s[], int limit);
void copy(char to[], const char from[]);

int line_input(char s[], int limit)
{
    int ch;
    int i = 0, index = 0;
    for(; ((ch = getchar()) != EOF) && (ch != '\n'); ++i)
    {
        if (index < limit - 1) s[index++] = ch;
    }
    if(ch == '\n')
    {
        if (index < limit - 1) s[index++] = ch;
    }
    else if(ch == EOF && index == 0)
    {
        return -1;
    }
    s[index] = '\0';
    printf("%d\n", i);
    return i;
}

void copy(char to[], const char from[])
{
    int i;

    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

int main(void)
{
    int length = 0;
    int max = 0;
    char line[MAXLINE], longest[MAXLINE];
    while((length = line_input(line, MAXLINE)) >= 0)
    {
        printf("%d\n%s\n", length, line);
        if(length > max)
        {
            max = length;
            copy(longest, line);
        }

    }
    if(max > 0)
    {
        printf("\n\n%d is the size of the longest line\n", max);
        printf("%s\n\n", longest);
    }
    return 0;
}

【讨论】:

  • 这种方法并不表示EOF 何时发生。建议在 EOFfgetc() 返回时返回 EOF
  • 不计算'\n',当出现仅由"\n"组成的行时,即使存在其他行,该函数也会停止OP的while((length = line_input(line, MAXLINE) &gt; 0))
  • 只是一点点,测试index + 1 &lt; limit 总是比index &lt; limit - 1 更安全。 (note 这是一个小的 nit,可以防止各种转换和符号扩展,例如,如果 limitunsigned 并且无意中为零)@chux 一定已经打了蛋酒过节的时候……他通常也会提出这个问题。 :)
  • @David C. Rankin 并且使用size_t 而不是int limit 通常更好地索引和限制数组的大小。 MCHNY。
  • @DavidC.Rankin 在这种情况下,如果index 是其类型的最大值,index + 1 将失败,因此没有硬性规定
【解决方案2】:

看看你的 line_input() 函数:

int line_input(char s[], int limit)
{
    char ch;
    int i = 0;
    for(; ((ch = getchar()) != EOF) && (ch != '\n'); ++i)
    {
        s[i] = ch;
    }
    if(ch == '\n')
    {
        s[i] = ch;
        ++i;
    }
    s[i] = '\0';
    printf("%d\n", i);
    return i;
}

当 'ch' 是换行符时,您只会增加变量 'i'。将增量放入 for 循环中,如下所示:

for(; ((ch = getchar()) != EOF) && (ch != '\n'); ++i){
    s[i] = ch;
    i++;
}

如果您愿意,可以通过保留或删除 if(ch == '\n') 正文中的增量来决定是否要保留换行符的增量。

【讨论】:

  • 我看到并纠正了这一点。感谢您指出这一点。由于多任务处理,我错过了它。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多