C语言,不同指针打开同一文件


#include 

int main()
{
    FILE *p1,*p2;
    p1 = fopen("a","w");
    p2 = fopen("a","w");
    fputc('B',p2);  //①
    fputc('A',p1);  //②
    fclose(p1);
    fclose(p2);
    return 0;
}

运行这段程序后a文件里的内容是B,交换①和②的顺序运行,文件内容还是B,只有删掉①再运行,文件内容才是A,这是为什么呢?

因为 p1 和 p2 以只写模式打开的同一个文件, 并且 p2 是 最后一个fclose 关闭的,所以结果总是 p2 写入的 ‘B’
文件访问模式,可参考我的这篇了解下:《C语言函数大全--f开头的函数(下)》

chatgpt:
这是因为在打开文件时使用了相同的文件名和文件访问模式("w"),这会导致第二个fopen()调用清空了文件内容并打开了一个新的空文件。因此,无论是在第一次还是第二次写入文件,实际上都是将一个字符写入了新创建的空文件中,因此最终文件中只有一个字符 "B"。如果您想让程序在同一个文件中追加数据,而不是清空文件并写入新数据,可以使用文件访问模式 "a",例如:


p1 = fopen("a", "a");
p2 = fopen("a", "a");

这样,每次写入文件时都会将数据追加到文件末尾,而不是清空文件并重新写入。

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/189722
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:猜单词游戏。计算机随机产生一个单词,打乱字母顺序,供玩家去猜 a.准备一组单词,随机抽取一个b.将抽取的单词作为答案,打乱字母顺序,显示给玩家,供其猜测c.猜测错误继续猜测或以空字符串.
  • 除此之外, 这篇博客: 关于链表的算法题(C语言实现)中的 4、已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 算法思想:求两个集合A和B的差集是指在A中删除A和B中共有的元素,即删除链表中的相应结点,所以要保存待删除结点的前驱,使用指针pre指向前驱结点。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果La表中的元素小于Lb表中的元素,pre置为La表的工作指针pa删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个为空时,依次删除另一个非空表中的所有元素。

    算法:

    /* 差集的结果存储于单链表La中,*n是结果集合中元素个数,调用时为0 */
    void Difference(LinkList& La, LinkList& Lb,int *n){
    
    	pa=La->next; pb=Lb->next;  ∥pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
    
    	 pre=La;         ∥pre为La中pa所指结点的前驱结点的指针
    
    	  while(pa&&pb){
    
    	    if(pa->data<q->data){pre=pa;pa=pa->next;*n++;} ∥ A链表中当前结点指针后移
    
    	    else if(pa->data>q->data)q=q->next;    ∥B链表中当前结点指针后移
    
    	       else {pre->next=pa->next;     ∥处理A,B中元素值相同的结点,应删除
    
    	         u=pa; pa=pa->next; delete u;}  ∥删除结点
    
    	}
    
    }