【问题标题】:c while loop keep running even when condition is falsec while循环在条件为假时继续运行
【发布时间】:2020-07-08 05:41:47
【问题描述】:

我已经编写了这段代码来处理文件,它以 256 字节的块读取文件

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

#define CHUNK_SIZE 256


int chunkable(size_t size, int chunk_size){
    return (size - chunk_size) > 0;
}

char * read_file(FILE *f, size_t fsize){
    char * fbuff = (char *) malloc(sizeof(char) * fsize);

    if(chunkable(fsize, CHUNK_SIZE)){
        while(fsize > 0){
            printf("reading chunk..., remaining: %d\n", fsize);
            fread(fbuff, CHUNK_SIZE, 1, f);
            fsize -= CHUNK_SIZE;
        }
    } else {
        fread(fbuff, CHUNK_SIZE, 1, f);
    }
    return fbuff;
}

int main(int argc, char *argv[]){
    FILE * f;
    int fsize;
    char * file_content;

    if(argc == 1){
        fprintf(stderr, "argument missing (filename) exiting...\n");
        return -1;
    }

    f = fopen(argv[1], "r");
    if(f == NULL){
        fprintf(stderr, "couldent open %s, exiting...\n", argv[1]);
        return -1;
    }
    
    fseek(f, 0, SEEK_END);
    fsize = ftell(f);
    fseek(f, 0, SEEK_SET);

    file_content = read_file(f, fsize);
    printf("file content: %s\n", file_content);
    
    free(file_content);
    fclose(f);
}

我在这条线上遇到的问题

while(fsize > 0){...}

每次从文件中读取块时,它都会从要读取的剩余字节中减去块大小,while 循环应该在没有剩余字节要读取时停止读取,但我得到的输出是

reading chunk..., remaining: 580
reading chunk..., remaining: 324
reading chunk..., remaining: 68
reading chunk..., remaining: -188
reading chunk..., remaining: -444
reading chunk..., remaining: -700
reading chunk..., remaining: -956
reading chunk..., remaining: -1212
reading chunk..., remaining: -1468
etc...

fsize 是一个负数,这意味着 fsize &gt; 0false,但 while 循环一直持续 4 次

【问题讨论】:

  • 不匹配 printf()-conversion 说明符的未定义行为。如果你启用警告,你的编译器会告诉你,除非你的编译器是垃圾。

标签: c while-loop


【解决方案1】:

sizesize_t 类型,这是一个无符号类型。因此,当您继续从 size 中减去 CHUNK_SIZE 时,该值将环绕为一个非常大的正值。

您在打印时看到负值的原因是您对printf 使用了错误的格式说明符。 %d 需要 int 参数。您应该使用%zu 代替size_t

您也没有检查fread 的返回值。您可能读取的字节数少于 CHUNK_SIZE 字节,或者您可能会遇到错误。您还每次都读入同一个缓冲区,覆盖以前存在的内容。

您需要捕获返回值并检查它。在此基础上,您从 size 中减去,并在 fbuff 中添加一个偏移量,以附加到您已经阅读的内容。

    char *p = fbuff;
    while(fsize > 0){
        printf("reading chunk..., remaining: %zu\n", fsize);
        size_t len = fread(p, CHUNK_SIZE, 1, f);
        if (len == 0) {
            printf("error reading\n");
            break;
        }
        fsize -= len;
        p += len;
    }
    *p = 0;  // null terminate the string for printing

【讨论】:

    猜你喜欢
    • 2021-02-07
    • 2021-08-02
    • 2015-07-26
    • 2021-12-20
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2023-01-11
    • 2019-10-26
    相关资源
    最近更新 更多