【问题标题】:Weird behavior of fread | A function behaves differently when called from main and differently when called from some other functionfread 的奇怪行为 |一个函数从 main 调用时的行为不同,而从其他函数调用时的行为不同
【发布时间】:2013-09-27 01:47:24
【问题描述】:

我编写了一个函数来从文件的指定位置读取给定数量的字节。从 main 调用时,这可以按预期工作。但是当它被其他一些函数调用时,它又被 main 调用,它也会读取某些额外的垃圾字符(其中一些是不可打印的)。

请解释发生了什么以及如何防止它发生。代码和相应的输出如下:

编辑:最终目标是计算此数据的哈希值,创建一个(数据 + 哈希值)数据包并通过 TCP 套接字将其发送到网络中的另一个节点。

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

char * read_from_file(char * filename, int offset, int n_bytes)
{
    printf("Inside read function\n");
    printf("offset: %d\n",offset);
    printf("n_bytes: %d\n",n_bytes);
    char * bfr;
    FILE * f_ptr;
    int count;

    f_ptr = fopen (filename,"r");
    if(f_ptr==NULL)
    {
        printf("File not found\n");
        exit(1);
    }
    //Set the offset position
    fseek(f_ptr, offset , SEEK_SET);
    //memory aloocation
    bfr = malloc (sizeof(char)*n_bytes);
    if (bfr == NULL)
    {
        printf("Memory allocation problem\n");
        exit (2);
    }
    count = fread(bfr,1,n_bytes,f_ptr);
    printf("no. of characters read from file: %d\n",count);
    printf("string read: %s\n", bfr);
    printf("Length of string read: %zd\n",strlen(bfr));

    if (count != n_bytes)
    {
        printf("Error in reading the file");
        exit(1);
    }
    // Close the file
    fclose (f_ptr);
    printf("Exiting read function\n\n");
    return bfr;
}

int send_file()//nc_args_t * nc_args)
{
    printf("Inside send_file\n");
    char * data;
    data = malloc (10);
    data = read_from_file("alphabet.txt", 0, 10);
    printf("Length of data: %d\n",strlen(data));
    printf("Data Read: %s\n", data);

}

int main()
{
    char * data;
    data = read_from_file("alphabet.txt", 0, 10);
    printf("Length of data: %zd\n",strlen(data));
    printf("Data Read: %s\n", data);
    printf("\nCalling send_file\n");
    send_file();
}

输出

Inside read function
offset: 0
n_bytes: 10
no. of characters read from file: 10
string read: ABCDEFGHIJ
Length of string read: 10
Exiting read function

Length of data: 10
Data Read: ABCDEFGHIJ

Calling send_file
Inside send_file
Inside read function
offset: 0
n_bytes: 10
no. of characters read from file: 10
string read: ABCDEFGHIJLsE
Length of string read: 14
Exiting read function

Length of data: 14
Data Read: ABCDEFGHIJLsE

【问题讨论】:

    标签: c pointers main fread


    【解决方案1】:

    通话后

    count = fread(bfr,1,n_bytes,f_ptr);
    

    bfr 不一定是字符串,因为它可能不是以 null 结尾的,因此您无法使用 printf("string read: %s\n", bfr); 打印其内容或使用 strlen 获取其长度。您需要循环打印每个字符:

    for (int i = 0; i < n_bytes; i++)
        printf("%c", bfr[i]);
    printf("\n");
    

    编辑

    感谢@Jonathan Leffer 的评论,这看起来好多了:

    printf("%.*s\n", count, bfr);
    

    【讨论】:

    • 如果bfr 不是\0 终止,那么其他字节可能不是不可打印的,因此%c 以外的格式是有保证的吗?或者如果只有文本跳过循环并使用printf("%.*s\n", n_bytes, bfr);?
    • @chux 你是对的,假设数据是任意二进制数据,打印十六进制会更好。这取决于OP想要什么,根据示例,数据是可打印的字符。
    • 您可以使用printf("%.*s\n", count, bfr); 假设读取的数据不包含任何零(空)字节。
    【解决方案2】:

    您没有为字符串的空终止符分配额外的字节,也不能保证存在终止符。您必须为缓冲区分配n_bytes + 1,并确保最后一个字节为零。

    【讨论】:

    • 实际上,我想计算它的哈希值,创建一个数据包并通过 TCP 套接字将其发送到其他网络。我还需要'\0'吗?
    • 我不知道您要发送的内容是否需要以空字符结尾的字符串或具有给定长度的字符数组。请查阅您要发送的 TCP 数据包的规范。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多