【问题标题】:fread not advancing the pointerfread 不推进指针
【发布时间】:2017-07-23 04:09:47
【问题描述】:

我正在使用 C 语言中的 fread()。我正在尝试读取二进制文件名 pds_demo.bin 的内容,但不知何故我的 fread 函数没有推进。我在 gdb 中检查了 fread() 的返回值,它返回 0。

我正在使用总共 3 个文件 pds_functions.cpds_test.cpds_demo.bin(包含阅读)。

pds_test.c 正在调用 pds_functions.c 中名为 pds_search_by_key() 的函数来检查特定内容。该函数检查演示文件的内容并返回记录是否存在的状态。我已包含以下所有文件。

任何形式的帮助将不胜感激。谢谢。

pds_test.c

void test_search() {
    int status;
    struct Contact c3;
    int key;
    key = 101;
    status = pds_search_by_key(key, &c3);
    if (status != PDS_SUCCESS) {
        fprintf(stderr, "pds_search_by_key failed for key %d: errorcode %d\n", key, status);
    } else {
        printContact(&c3);
    }
    key = 102;
    status = pds_search_by_key(key, &c3);
    if (status != PDS_SUCCESS) {
        fprintf(stderr, "pds_search_by_key failed for key %d: errorcode %d\n", key, status);
    } else {
        printContact(&c3);
    }
    key = 1020000;
    status = pds_search_by_key(key, &c3);
    if (status != PDS_SUCCESS) {
        fprintf(stderr, "pds_search_by_key failed for key %d: errorcode %d\n", key, status);
    } else {
        printContact(&c3);
    }
}

pds_functions.c

int pds_search_by_key(int key, struct Contact *c) {

    fseek(repo_fptr, 0L, 0);

    if (pdsInfo.repo_status == 1) {
        while (!feof(repo_fptr)) {
            fread(c, sizeof(struct Contact), 1, repo_fptr);
            if (c->contact_id == key) {
                return PDS_SUCCESS;
            }
        }
        return PDS_REC_NOT_FOUND;
    }
    return PDS_REPO_NOTOPEN;
}

pds_demo.bin

101 Contact #1 Phone #1 Email #1 102 Contact #2 Phone #2 Email #2 102 Contact #2 Phone #2 Email #2 

还有一个结构体定义了结构体Contact。

struct Contact {
    int contact_id;
    char cname[MAX_NAME_LEN];
    char mphone[MAX_PHONE_LEN];
    char email[MAX_EMAIL_LEN];
};

另外,当我使用 gdb 调试程序时,*c 的内容如下:

(gdb) p *c
$1 = {contact_id = 540094513, cname = "Contact #1 Phone #1 Email #1 102 
Contact #2 Phone ", mphone = "#2 Email #2", 
  email = " 102 Contact #2 Phone #2 Email #2 \377\377\177\000\000\t\t@\000\000\000\000\000\000\000"}

【问题讨论】:

  • 我需要做哪些改变?
  • 需要注意的一点是fread 读作cstruct Contact 的一种类型,但size_t 参数是1
  • fread(c, 1, 1, repo_fptr); 读取单个字节,并且您不检查它是否成功。如果c 不是char——它不是——你需要更像if (fread(c, sizeof(*c), 1, repo_fptr) != 1) { /* oops — nothing read */ }
  • 看来你是用文字写的,没有使用fwrite

标签: c file-io fread


【解决方案1】:

您的代码存在重大问题:

  • 您的阅读循环不正确,请看这里:Why is “while ( !feof (file) )” always wrong?

  • 您正在从文件中读取固定长度的结构,您必须以二进制模式读取和写入文件,fopen 必须分别通过"rb""wb" 才能以二进制模式打开文件。

如果文件以二进制模式打开,则可以这样修改读取循环:

int pds_search_by_key(int key, struct Contact *c) {

    fseek(repo_fptr, 0L, 0);

    if (pdsInfo.repo_status == 1) {
        while (fread(c, sizeof(*c), 1, repo_fptr) == 1) {
            if (c->contact_id == key) {
                return PDS_SUCCESS;
            }
        }
        return PDS_REC_NOT_FOUND;
    }
    return PDS_REPO_NOTOPEN;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2012-09-15
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    相关资源
    最近更新 更多