c语言fopen追加模式下fseek失效

本文探讨了C语言中使用fseek定位文件指针的问题,特别是在以追加模式打开文件时遇到的挑战。文章通过示例代码展示了在ab模式下fseek无法正确工作的情况,并给出了将文件打开模式更改为rb+作为解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载:http://www.cnblogs.com/rusty/archive/2011/11/17/2253069.html

 
 

 

用到编程改变文件某个字段的值,结果发现此现象。上代码:

int writepcap(char *filename,int begin,int len,char *content)
{
    if(!pcap || !content)
        return -1;
    FILE *fp = NULL;
    fp = fopen(filename,"ab");//rb+
    if(!fp)
        return -2;
  if(-1 == fseek(fp,begin,SEEK_SET))
  {
      fclose(fp);
      return -3;
  }
  //printf("curr:%ld\n",ftell(fp));
  if(fwrite(content, sizeof(unsigned char), len, fp) <= 0)
  {
       fclose(fp);
      return -4;    
  }
  fclose(fp);
  return 0;
}

 

结果发现ftell输出的位置是正确的,但是写的时候还是写在了最后面。

在linux下,man fopen看到:

a+     Open for reading and appending (writing at end of file).  The file is created if it does not exist.  The initial file 
       position for  reading is at the beginning of the file, but output is always appended to the end of the file.

 

原来如此。

解决办法:改为rb+即可。

<think>我们正在讨论C语言中如何使用fopen函数以追加模式打开文件,确保新内容添加到文件末尾而不覆盖原有内容。 根据引用[1]和[3],我们可以使用模式"a"(追加模式)来打开文件。在这种模式下,如果文件存在,写入操作将在文件末尾进行;如果文件不存在,则会创建新文件。 引用[1]中的例子:fopen("log.txt", "a"),然后使用fprintf写入,最后关闭文件。 步骤: 1. 使用fopen模式"a"打开文件。 2. 检查文件指针是否为NULL,以确保文件打开成功(引用[4])。 3. 使用fprintf、fputs等函数写入内容。 4. 关闭文件。 示例代码: 假设我们要向文件"data.txt"追加一行"new data line"。 注意:追加模式不会覆盖原有内容,每次写入都会从文件末尾开始。</think>在 C 语言中,使用 `fopen()` 函数以**追加模式**打开文件可以确保新内容添加到文件末尾而不覆盖原有数据,具体实现如下: ### 一、追加模式的核心用法 ```c #include <stdio.h> int main() { // 以追加模式打开文件("a"表示追加) FILE *file = fopen("data.txt", "a"); if (file == NULL) { perror("文件打开失败"); return 1; } // 向文件末尾追加新内容 fprintf(file, "new data line\n"); // 关闭文件 fclose(file); return 0; } ``` ### 二、关键机制解析 1. **打开模式 `"a"`**: - 文件存在时:文件指针定位到**末尾**,新内容追加到现有数据之后[^1][^3] - 文件不存在时:自动创建新文件[^1] - 与 `"w"`(覆盖写)模式本质区别:**不擦除原内容**[^3] 2. **写入函数选择**: ```c // 推荐方式(自动处理格式) fprintf(file, "追加内容:%d\n", value); // 简单字符串追加 fputs("new data line", file); ``` 3. **安全验证**: ```c if (file == NULL) { // 处理失败场景(文件不存在/权限不足等) printf("错误代码:%d\n", errno); perror("fopen失败原因"); } ``` ### 三、多场景应用示例 #### 1. 追加结构化日志 ```c void log_event(const char* msg) { FILE *log = fopen("app.log", "a"); if (log) { fprintf(log, "[%s] %s\n", get_current_time(), // 时间戳函数 msg); fclose(log); } } ``` #### 2. 带错误恢复的追加 ```c FILE *file = fopen("data.txt", "a"); if (!file) { // 尝试创建文件 file = fopen("data.txt", "w+"); if (!file) exit(EXIT_FAILURE); } fprintf(file, "恢复后追加的内容\n"); fclose(file); ``` ### 四、模式对比表 | 模式 | 文件存在时行为 | 文件不存在时 | 指针位置 | |------|----------------------|--------------|----------| | `"a"` | **追加**到末尾 | 创建新文件 | 文件末尾 | | `"w"` | **清空**后写入 | 创建新文件 | 文件开头 | | `"r+"`| 读写(不截断) | 返回失败 | 文件开头 | | `"a+"`| 读写追加(可读末尾) | 创建新文件 | 文件末尾 | > **底层原理**:追加模式通过 `O_APPEND` 标志实现(Linux 系统调用),保证每次写入前自动定位到文件末尾[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值