fread fgets feof 读文件到buf里面

本文介绍了一种从dhcp.leases文件中读取并处理数据的方法,使用fgets逐行读取文件内容,并通过strcat将内容追加到指定缓冲区。此外,还展示了如何比较Wi-Fi MAC地址以及调用系统命令获取输出。

从dhcp.leases读文件,每次读一行,fgets,写到dst_dhcp_list指向的buf里面。

feof(fp)有两个返回值:如果遇到文件结束,函数feof(fp)的值为非零值,否则为0。

int conf_get_dhcp_list1_new(char* dst_dhcp_list)
{
    FILE *f=NULL;
    char line_buffer[256]={0};
    my_printf(LOG_MODE_LEVEL_1, "%s(%d) sizeof(line_buffer):%d\n",__FUNCTION__,__LINE__,sizeof(line_buffer));

    if ((f = fopen("/tmp/dhcp.leases", "r")) != NULL)
    {

        while (!feof(f)) // If the file ends, the value of the function feof(fp) is non-zero, otherwise 0.
        {
           fgets(line_buffer,sizeof(line_buffer),f);
           strcat(dst_dhcp_list, line_buffer);
           my_printf(LOG_MODE_LEVEL_1, "%s(%d) conf_get_dhcp_list1 accessed and dst_dhcp_list is:\n%s\n",__FUNCTION__,__LINE__,dst_dhcp_list);
        }

    }

    fclose(f);
    return 0;
}

    while(fgets(wifimac, sizeof(wifimac), fd) != NULL)
    {
        if(strncmp(uppermac,wifimac,17) == 0)
        {

            my_printf(1, "%s(%d) COMPARE SUCCESED wifiMAC is %s uppermac is %s \n",__FUNCTION__,__LINE__,wifimac,uppermac);
            return 1;
        }   
        my_printf(1, "%s(%d) wifiMAC is %s mac is %s \n",__FUNCTION__,__LINE__,wifimac,uppermac);

    }

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

/*****************************************************************
*Function: get_system_output
*Description:call the system command,gets the return value of the command.
*Input:cmd
*Input:size
*Output:output
*****************************************************************/
static int get_system_output(char *cmd, char *output, int size)
{
    FILE *fp=NULL;  
    fp = popen(cmd, "r");   
    if (fp)
    {       
        if(fgets(output, size, fp) != NULL)
        {       
            if(output[strlen(output)-1] == '\n')            
                output[strlen(output)-1] = '\0';    
        }   
        pclose(fp); 
    }
    return 0;
}


int main(int argc, char **argv)
{

    char *p_file="./data.txt";  
    char *p_file_bck="./data.bck";  
    FILE *f=NULL;
    char str[1024]={0};
    char line_buffer[1024]={0};
    char *p_line_buffer = NULL;
    char *pcmd = NULL;
    char cmd[1024]={0};
    char file_info[64][1024]={'0'};
    char *p=NULL;
    int i=0,j=0;

    if (access(p_file,R_OK) !=0 )
    {
        printf(">>>>>>>>>>./data.txt ERROR! \n");
        return;
    }

    system("awk '{print($2)}' ./data.txt > ./data.bck");


    if ((f = fopen(p_file_bck, "r")) != NULL)
    {
        while (fgets(line_buffer,sizeof(line_buffer),f),!feof(f)) // If the file ends, the value of the function feof(fp) is non-zero, otherwise not file end 0.
        {
          // fgets(line_buffer,sizeof(line_buffer),f);  //fread(line_buffer, 1024, 1, f);

           memset(str, 0x0, sizeof(str));
           strcpy(str, line_buffer);

           if ( (str[strlen(str)-2] == '\n')  || (str[strlen(str)-2] == '\r') )
               str[strlen(str)-2]='\0'; 

           if ( (str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r') )
               str[strlen(str)-1]='\0'; 

           //copy to ~/lin/push_code/
           memset(&cmd, 0x0, sizeof(cmd));
           strcat(cmd, "cp ");
           strcat(cmd, str);
           strcat(cmd, "   ~/lin/push_code/");
           printf("###copy to:%s\n",cmd);
           //system(cmd);


#if 1      
           //svn di to ~/lin/push_code/
           memset(&cmd, 0x0, sizeof(cmd));
           strcat(cmd, "svn di ");
           strcat(cmd, str);
           strcat(cmd, "  >  ~/lin/push_code/diff");

           p = strrchr(str, '/');
           //printf("###p:\n%s\n",p);
           strcat(cmd, p);
          // system(cmd);
           printf("###svn di to:%s\n",cmd);
#endif   

        }

    }
    else
    {
        printf(">>>>>>>>>>./data.txt ERROR!! \n");
    }


    return 0;
}

<think>首先,用户的问题是关于C语言中fread函数在取到空字符(即'\0')时的行为。用户问:"fread取到空字符/0时会怎样处理"。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证回答真实可靠。 参考提供的引用: - [^1] 讨论了fread函数的内部实现,包括FILE结构体的指针。 - [^2] 解释了fread函数的基本用法和原型。 - [^3] 展示了fread的使用示例。 - [^4] 提到了文本和二进制模式下的区别。 - [^5] 涉及了字节序问题。 关键点: - fread函数从文件流中读取数据,不关心数据的内容,包括空字符。它只是取字节序列。 - 在二进制模式下,fread取所有字节,包括'\0',不会进行任何特殊处理。 - 在文本模式下,可能会处理换行符,但空字符'\0'通常不会被特殊处理;它只是作为数据的一部分。 用户问题:取到空字符'\0'时,fread会怎样处理? - fread会正常取'\0'字符,就像取任何其他字节一样。它不会停止或改变行为,因为'\0'在C语言中表示字符串结束,但fread不是字符串函数;它是二进制取函数。 详细回答: - fread的原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); - 它取nmemb个元素,每个元素size字节,从stream到ptr指向的缓冲区。 - 取到的数据包括任何字节,包括'\0'。fread不会解释数据内容;它只是复制字节。 - 因此,如果文件中包含'\0',fread取它,并存储在缓冲区中。 在文本模式和二进制模式的区别: - 根据引用[^4],文本模式会处理回车换行符('\n'转换为'\r\n'或反之),但对于空字符'\0',没有特殊处理。'\0'在文本模式下也是直接取的。 - 在二进制模式下,没有转换,所有字节原样取。 所以,行为是:fread取到'\0'时,会将其作为普通字节处理,复制到缓冲区。 回答结构: 1. 解释fread的基本行为。 2. 强调fread不关心数据内容。 3. 讨论模式和空字符的影响。 4. 提供示例或引用支持。 5. 生成相关问题。 生成相关问题: - 基于用户查询,相关问题应该围绕fread函数、文件取、空字符处理等。 相关问题建议: 1. fread在文本模式和二进制模式下处理空字符有什么不同? 2. 如何安全地取包含空字符的文件? 3. freadfgets在处理字符串时有什么区别? 4. 为什么fread取二进制文件时可能出错? 5. fread取到文件结束时的行为是什么? 确保回答真实可靠: - 基于C语言标准和常见实现。 - 引用提供的参考来支持。 最终回答用中文。</think>### fread函数取空字符(\0)时的行为 在C语言中,fread函数是用于从文件流中读取数据的底层函数,其行为取决于文件打开模式(文本或二进制),但不会对数据内容进行解释或转换。以下是针对您问题的详细分析: 1. **fread的基本行为**: - fread函数原型为:`size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);`,它会从`stream`中取`nmemb`个元素(每个元素大小为`size`字节),并将数据存储到`ptr`指向的缓冲区中。 - 当取到空字符(`\0`,ASCII值为0)时,fread**不会特殊处理**它。空字符被视为普通字节,与其他数据(如字母或数字)一样被复制到缓冲区中[^2][^4]。 - 例如,如果文件包含序列`"hello\0world"`,fread会完整取11个字节(包括中间的`\0`),而不会截断或跳过。 2. **文本模式 vs. 二进制模式**: - **二进制模式**(文件以`"rb"`打开): - fread会原样取所有字节,包括空字符`\0`,不做任何转换。这意味着缓冲区中会包含完整的原始数据,空字符被保留为二进制0[^4][^5]。 - 例如,取一个包含`\0`的结构体时,fread会正确复制所有字节,即使其中有空字符[^4]。 - **文本模式**(文件以`"r"`打开): - 文本模式主要影响换行符的处理(如将`\r\n`转换为`\n`),但**对空字符`\0`没有特殊转换**。fread仍会将`\0`作为普通字节取到缓冲区中[^2][^4]。 - 然而,在文本模式下,如果文件包含平台特定的换行符序列,fread可能会调整这些字节,但空字符不受影响。 3. **潜在问题与注意事项**: - **缓冲区溢出风险**:如果使用fread取包含`\0`的数据到字符串缓冲区(如`char buf[100]`),后续用字符串函数(如`printf`或`strlen`)处理时,可能会在第一个`\0`处截断,导致数据不完整。但这不是fread的问题,而是缓冲区使用方式导致的[^2][^3]。 - **文件结束与错误**:如果fread返回的元素数少于请求的`nmemb`,可能表示遇到文件结束或错误(可通过`feof()`或`ferror()`检查),但这与空字符无关[^2][^5]。 - **内部指针管理**:fread通过`FILE`结构体的指针(如`_IO_read_ptr`)跟踪取位置,取空字符时,这些指针正常移动,不会重置或跳过[^1]。 4. **示例代码**: ```c #include <stdio.h> int main() { FILE *fp = fopen("test.bin", "rb"); // 二进制模式打开 char buffer[20]; size_t num_read = fread(buffer, 1, sizeof(buffer), fp); if (num_read > 0) { // 缓冲区可能包含 \0,但fread已完整取 for (int i = 0; i < num_read; i++) { printf("Byte %d: %x\n", i, (unsigned char)buffer[i]); } } fclose(fp); return 0; } ``` - 如果`test.bin`包含`"A\0B"`,输出会显示三个字节:`0x41`, `0x00`, `0x42`,证明`\0`被正确取。 **总结**:fread函数在取到空字符`\0`时,会将其视为普通数据字节,不做任何特殊处理(如截断或跳过)。行为在文本和二进制模式下一致,但二进制模式更可靠,因为它避免了换行符转换的干扰。如果您需要将数据作为字符串处理,建议手动检查缓冲区中的`\0`或使用字符串函数(如`fgets`)[^2][^3][^4]。 ### 相关问题 1. [fread在文本模式和二进制模式下处理空字符有什么不同?](#) 2. [如何安全地取包含空字符的文件以避免缓冲区问题?](#) 3. [freadfgets在处理文件数据时的主要区别是什么?](#) 4. [为什么fread取二进制文件时可能返回零或错误?](#) 5. [fread取到文件结束时的行为如何检测?](#)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值