为什么 getw 不显示文件中的所有数字?

Why does getw not display all of the numbers in the file?

提问人:Lucas Aquino de Assis 提问时间:8/28/2022 更新时间:8/29/2022 访问量:61

问:

我已经按照本教程实现了一个程序,该程序可以生成多达 100,000 个随机数并将它们插入到要排序的文件中,但我注意到循环输出的数字比预期的要少得多。在我的机器中,此代码仅打印 49 个数字:getw

#include <stdio.h>
#include <stdlib.h>

int gen_random_file(int n_values) {
    int index;
    int num, num_count = 0;
    FILE *r_file;
    r_file = fopen("random_numbers", "w");

    if (r_file != NULL) {
        printf("File created successfully!\n");
    }
    else {
        printf("Failed to create the file.\n");
        return -1;
    }

    for (index = 0; index < n_values; index++) {
        putw(rand(), r_file);
    }

    fclose(r_file);

    r_file = fopen("random_numbers", "r");

    // display numbers
    printf("\nNumbers:\n");
    while ( (num = getw(r_file)) != EOF ) {
        printf("%d\n", num);
        num_count++;
    }
    printf("\nEnd of file.\nNum Count = %d\n", num_count);

    fclose(r_file);

    return 0;
}

int main()
{
    gen_random_file(10000);

    return 0;
}
C 文件 排序 std

评论

1赞 Some programmer dude 8/28/2022
读者注意:并且可能是特定于 Windows 的_putw_getw功能。putwgetw
2赞 Weather Vane 8/28/2022
以二进制模式打开文件。请注意,_getw状态 但是,由于 EOF 值也是合法的整数值,因此请使用 feofferror 来验证文件结束或错误条件。文本模式转换可能使预期数据未对齐,导致出现实际未写入的数据。"rb"-1
1赞 Some programmer dude 8/28/2022
对 OP:注意等于 。这是一个有效值,因此无法区分实际有效值和 。这是您使用的功能的一个主要缺陷。如果要写入和读取原始二进制数据,请改用 fwritefread。如前所述,请记住以 binary 模式打开文件。EOF-1int-1EOF
2赞 Weather Vane 8/29/2022
@Someprogrammerdude Visual C 生成 .. 范围内的 vlaues。 但是,在文本模式下阅读导致的错位可能会造成伪影。rand()032767-1
0赞 Chris Dodd 8/29/2022
@Someprogrammerdude:和 是 SYSVr4 的“标准”函数,因此早于 windows,并且存在于大多数 UNIX 系统上,即使它们不是 POSIX 的一部分putwgetw

答:

2赞 user58697 8/29/2022 #1

您过早地终止了循环。 可能会偶尔产生。rand()-1

引用(Bugs 部分):man getw

由于 EOF 是一个有效的整数值,因此在调用 getw() 后必须使用 feof(3) 和 ferror(3) 来检查失败。

你需要这样的东西

    while(1) {
        if ((w = getw()) == EOF) {
            if (feof(stdin) || ferror(stdin)) {
                break;
            }
        printf(....);
        ....
    }
    // Deal with error if necessary
0赞 Chris Dodd 8/29/2022 #2

这是您真正想要 feof 的罕见情况之一。你需要一个循环,比如

while ((num = getw(r_file)), !feof(r_rile)) {

读取一个数字,然后测试 EOF。

在某些系统(如 Windows)上,您还需要 和 for 您的 fopen 模式来获取二进制文件。"wb""rb"

0赞 Lucas Aquino de Assis 8/29/2022 #3

我最终使用了 和 以及 和 作为 fopen 的参数,这解决了这个问题。fwritefread"wb""wr"

#include <stdio.h>
#include <stdlib.h>

int gen_random_file(int n_values) {
    int index;
    int rand_num, num_count = 0;
    int buffer[100000];
    FILE *rand_file;

    rand_file = fopen("random_numbers", "wb");

    if (rand_file != NULL) {
        printf("File created successfully!\n");
    }
    else {
        printf("Failed to create the file.\n");
        return -1;
    }

    for (index = 0; index < n_values; index++) {
        rand_num = rand();
        fwrite(&rand_num, sizeof(rand_num), 1, rand_file);
    }

    fclose(rand_file);

    rand_file = fopen("random_numbers", "rb");

    // display numbers
    printf("\nNumbers:\n");
    fseek(rand_file, 0, SEEK_SET);
    fread(buffer, sizeof(rand_num), n_values, rand_file);
    for (index = 0; index < n_values; index++) {
        rand_num = buffer[index];
        printf("%d\n", rand_num);
        num_count++;
    }
    printf("\nEnd of file.\nNum Count = %d\n", num_count);

    fclose(rand_file);

    return 0;
}

int main()
{
    gen_random_file(10000);

    return 0;
}