c - 新手C数组关于函数的问题

标签 c arrays function

我买了一本名为《The C (ANSI C) PROGRAMMING LANGUAGE》的 C 书来尝试自学 C。无论如何,这本书包含了很多示例和实践,可以在各章中遵循,这很好。

无论如何,下面的代码是我对《计算程序的最长行类型》一书的回答,作者在函数 getLine(char s[], int lim) 中使用了 for 循环。这允许正确显示字符串 line里面main()功能。然而,使用 while 是行不通的 - 出于我未知的原因,也许有人可能会阐明我的错误是什么。

编辑:总结以上内容。 printf("%s\n", line);不会显示任何内容。

感谢您的帮助。

#include <stdio.h>
#define MAXLINE 1024

getLine(char s[], int lim) {
    int c, i = 0;

    while((c = getchar()) != EOF && c != '\n' && i < lim) {
        s[++i] = c;
    }

    if(c == '\n' && i != 0) {
        s[++i] = c;
        s[++i] = '\0';
    }    
    return i;
}  

main(void) {
    int max = 0, len;
    char line[MAXLINE], longest[MAXLINE];

    while((len = getLine(line,MAXLINE)) > 0) {
        if(len > max) {
            max = len;
            printf("%s\n", line);
        }
    }
    return 0;
}

最佳答案

您有许多严重的错误。这是我发现的问题以及如何修复它们。

将代码更改为 postincrement i 以避免第一个数组成员未初始化,并避免重复打印最终字符:

s[++i] = c;
...
s[++i] = c;
s[++i] = '\0';

s[i++] = c;
...
// s[++i] = c; see below
...
s[i++] = '\0'; 

并修复您的 EOF 错误:

if(c == '\n' && i != 0) {
    s[++i] = c;
    s[++i] = '\0';
}

if(c == '\n')
{
    s[i++] = '\n';
}
s[i] = '\0'

理论

在编写处理字符串、数组或其他 vector 类型结构的程序时,检查程序的逻辑非常重要。您应该手动执行此操作,并通过它运行一些示例案例,为您的程序提供示例输入并思考会发生什么。

您需要运行的情况是:

  • 几个一般情况
  • 所有边缘情况

在这种情况下,您的边缘情况是:

  • 第一个字符是 EOF
  • 第一个字符是“x”,第二个字符是 EOF
  • 第一个字符是 '\n',第二个字符是 EOF
  • 第一个字符是“x”,第二个字符是“\n”,第三个字符是EOF

  • 一行有等于 lim 个字符

  • 一行少于 lim 个字符
  • 一行多于 lim 个字符

边缘情况示例

第一个字符是“x”,第二个字符是“\n”,第三个字符是EOF

getLine(line[MAXLINE],MAXLINE])
(s := line[MAXLINE] = '!!!!!!!!!!!!!!!!!!!!!!!!...'
c := undef, i := 0
while(...)
c := 'x'
i := 1
s[1] := 'x' => s == '!x!!!!...' <- first bug found
while(...)
c := '\n'
end of while(...)
if (...)
(c== '\n' (T) && i != 0 (T)) = T
i := i + 1 = 2
s[2] = '\n' => s == '!x\n!!!!'
i := i + 1 = 3
s[3] = '\0' => s == '!x\n\0!!!' <- good, it's terminated
return i = 3
(len = i = 3) > 0) = T (the while eval)
if (...)
len (i = 3) > max = F
max = 3 <- does this make sense?  is '!x\n' a line 3 chars long?  perhaps.  why did we keep the '\n' character? this is likely to be another bug.
printf("%s\n", line) <- oh, we are adding ANOTHER \n character?  it was definitely a bug.
outputs "!x\n\n\0" <- oh, I expected it to print "x\n".  we know why it didn't.
while(...)
getLine(...)
(s := line[MAXLINE] = '!x\n\0!!!!!!!!!!!!!!!!!!!...' ; <- oh, that's fun.
c := undef, i := 0
while(...)
c := EOF
while terminates without executing body
(c == '\n' && i != 0) = F
if body not executed
return i = 0
(len = i = 0 > 0) = F
while terminates
program stops.

因此,您会看到这个简单的过程,可以在您的脑海中完成,也可以(最好)在纸上完成,可以在几分钟内向您展示您的程序是否有效。

通过跟踪其他边缘情况和一些一般情况,您将发现程序中的其他问题。

关于c - 新手C数组关于函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2141211/

相关文章:

c - 如何用 clone() 替换 pthread_join() 和 pthread_create()

c - "lvalue required in asm statement"错误

php - 如何在 Javascript 中加入带有自定义索引的数组项?

javascript - 无法理解函数工作中一行的使用

jquery - 等待其他函数中的动画完成

c# - 在 ASP.NET MVC 5 中,在我应用迁移来更改 MODEL 类后,它也会更改我的 View .cshtml 文件吗?

c - 用于密码的 PBKDF2-HMAC-SHA1——C 中的示例?

java - 使用字符串输入中的字符填充二维数组

arrays - 数组 VBA 中的用户定义对象

C 段错误 : fscanf in a function