函数未正确地将变量递增 1

Function is not correctly incrementing variable by 1

提问人:Jason Fan 提问时间:10/11/2022 最后编辑:Vlad from MoscowJason Fan 更新时间:10/11/2022 访问量:53

问:

我有一个函数,可以返回数组中的行数、字符数和单词数。出于某种原因,当我遍历数组以打印值时,我只得到行的更正值,字符和单词返回为 0。所有的功能都是由我的教授预先确定的,我的工作就是填补它们。

int main(int argc, char **argv)
{
        int *myArray = get_counts(argv[1]);
        for (int i = 0; i < 3; i++)
        {
                printf("%d\n", myArray[i]);
        }
        return 0;
}
int *get_counts(char *filename)
{
        FILE *file;

        file = fopen(filename, "r");

        if (file == NULL)
        {
                printf("NULL FILE");
        }

        char c;
        int h;
        bool whitespace = true;
        static int arr[3] = {0,0,0};

        do
        {
                c = fgetc(file);
                if (c == '\n')
                {
                        arr[0] ++;
                }
        }while (c != EOF);

        while (true)
        {
                h = fgetc(file);

                if (feof(file))
                {
                        break;
                }
                else if (ferror(file))
                {
                        printf("error reading file");
                }
                arr[2] ++;

                if (whitespace && !isspace(h))
                {
                        arr[1] ++;
                        whitespace = false;
                }
                else if (!whitespace &&isspace(h))
                {
                        whitespace = true;
                }
        }
        fclose(file);
        return arr;
}
c fopen do-while eof

评论

0赞 Ken White 10/11/2022
使用调试器逐步执行代码,以帮助找出逻辑错误的位置以及出了什么问题。如果您不知道如何使用调试器,现在是开始学习的最佳时机。调试器是程序员可用的最强大的工具,开始使用调试器永远不会太早。
0赞 Vlad from Moscow 10/11/2022
@Jason风扇 在第一个 do-while 循环之后,EOF 条件发生。
0赞 Allan Wind 10/11/2022
如果 fopen 失败,您需要执行一些操作,而不是像往常一样继续。
0赞 Chris Dodd 10/12/2022
使用变量(例如 )来保存 的返回值是危险的,因为它无法保存所有可能的返回值(EOF(-1) 或 0..255)。充其量,如果您的文件包含0xff字符,它将被视为过早的 EOF。在最坏的情况下(在未签名的系统上),它永远不会终止。charcfgetcchar

答:

0赞 Vlad from Moscow 10/11/2022 #1

在第一个 do-while 循环之后,将出现条件 EOF。

    do
    {
            c = fgetc(file);
            if (c == '\n')
            {
                    arr[0] ++;
            }
    }while (c != EOF);

所以下面的while循环没有效果。

您应该只使用一个循环来计算行、单词和字符。

请注意,变量应声明为具有cint

int c;

此外,如果文件未打开,则需要退出该功能。

0赞 Allan Wind 10/11/2022 #2

最好的选择可能是在一个循环中遍历文件(您也可以在第一个循环之后)。使用返回值 of 来确定您处于的位置,而不是单独的调用。我还使结果数组成为 (out) 参数,而不是使用静态变量(如果您想从多个线程调用它,后者是不可重入的,并且很容易做到):rewind()fgetc()EOFfeof()

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

void get_counts(char *filename, int arr[3]) {
    memset(arr, 0, 3 * sizeof(int));
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        printf("NULL FILE");
        return;
    }
    bool whitespace = true;
    for(;;) {
        int c = fgetc(file);
        if(c == EOF)
            break;
        else if(c == '\n')
            arr[0]++;
        else if (whitespace && !isspace(c)) {
            arr[1]++;
            whitespace = false;
        } else if (!whitespace && isspace(c))
            whitespace = true;
        arr[2]++;
    }
    fclose(file);
}

int main(int argc, char **argv) {
    int myArray[3];
    get_counts(argv[1], myArray);
    for (int i = 0; i < 3; i++) {
        printf("%d\n", myArray[i]);
    }
}

上述文件的输出为:

39
94
715

字数 94 不同意,但您可以使用不同的单词定义。wc -w

最好将计算和 I/O 分开,因此请考虑打开和关闭文件并传入文件句柄。例如,如果您不想使用物理文件,则很容易使用文件句柄。main()stdin