int PrintList(listPtr List, char *DataFmt) /* Print List using DataFmt as the printf() format for Node Data Elements */ { int Count; listnodePtr Position; char OutStr[30]; if (List == NULL) return LLIST_BADVALUE; if (List->Flags & LISTBTREE) return PrintTree(List, DataFmt); strcpy(OutStr, "\tHead: "); strcat(OutStr, DataFmt); strcat(OutStr, "\tTail: "); strcat(OutStr, DataFmt); strcat(OutStr, "\n"); printf(OutStr, GetNodeData(List->Head), GetNodeData(List->Tail)); strcpy(OutStr, "Index: %d\tData: "); strcat(OutStr, DataFmt); strcat(OutStr, "\n"); Position = List->Current; List->Current = List->Head; for (Count = 1; Count <= List->Size; Count++) { printf(OutStr, Count, GetNodeData(List->Current)); NextNode(List); } List->Current = Position; return LLIST_NOERROR; } /* PrintList */
void GraphicTree(listnodePtr Node, char *DataFmt, int Level) /* Recursive procedure to print the structure of a binary tree. From example code by Matthew Weathers at Biola University */ { int Count; char OutStr[30]; if (Node != NULL) { for (Count = 0; Count < Level; Count++) printf("\t"); strcpy(OutStr, "\""); strcat(OutStr, DataFmt); strcat(OutStr, "\" (left=\""); strcat(OutStr, DataFmt); strcat(OutStr, "\", right=\""); strcat(OutStr, DataFmt); strcat(OutStr, "\")\n"); printf(OutStr, GetNodeData(Node), GetNodeData(Node->Prev), GetNodeData(Node->Next)); GraphicTree(Node->Prev, DataFmt, Level + 1); GraphicTree(Node->Next, DataFmt, Level + 1); } }
void showInfo() { //StringList show=InitStringList(); int i; Xref xref; for(i=0;i<xrefs->length;i++){ xref=(Xref)GetNodeData(xrefs,i); printf("%d----\n",i+1); printf("XrefOffset: %d\n",xref->xrefOffset); printf("Prev: %d\n",xref->trailer->Prev); printf("XRefStm: %d\n",xref->trailer->XRefStm); } printf( "----\n"); printf("InfoAt: %d\n",InfoAt); printf("%d xrefs\n", xrefs->length); for(i=0;i<xrefs->length;i++){ xref=(Xref)GetNodeData(xrefs,i); printf( "%s\n",xref->trailer->Prototype) ; } printf("PDFInfo:\n"); printf("Title: "); printUnicode(Title); printf("\nAuthor: "); printUnicode(Author); printf("\nSubject: "); printUnicode(Subject); printf("\nKeywords: ");printUnicode(Keywords); printf("\nCreationDate: ");printUnicode(CreationDate); printf("\nModDate: ");printUnicode(ModDate); printf("\nCreator: ");printUnicode(Creator); printf("\nProducer: ");printUnicode(Producer); printf("\nAdditive Attributes:\n"); Attr attr; for(i=0;i<Attrs->length;i++){ attr=(Attr)GetNodeData(Attrs,i); printf("%d\t",i+1); printUnicode(ReadTagString(attr->Name)); printf("\t"); printUnicode(attr->Value); printf("\n"); } if(Tail==0)return; printf("\nTail Attributes:\n"); for(i=0;i<Tails->length;i++){ attr=(Attr)GetNodeData(Tails,i); printf("%d\t",i+1); printUnicode(ReadTagString(attr->Name)); printf("\t"); printUnicode(attr->Value); printf("\n"); } /*return show;*/ }
static void ListCmdFn(cmdScannerADT cs) { scannerADT scanner; symtabADT nodeTable; graphADT graph; nodeADT node, target; graph = GetCommandData(cs); foreach (node in Nodes(graph)) { printf("%s:", (string) GetNodeData(node)); foreach (target in ConnectedNodes(node)) { printf(" %s", (string) GetNodeData(target)); }
//将int值转化为字符串 LPSTR IntToString(int num) { List list=InitList(); int sign,i; LPSTR output; if(num==0) return "0"; sign=num>0?1:-1; num=num*sign; while(num!=0) { AddNode(list,(void*)(num%10+48)); num/=10; } if(sign==-1) { AddNode(list,(void*)'-'); } output=(LPSTR)malloc(sizeof(char)*(list->length+1)); for(i=0;i<list->length;i++) { *(output+i)=(char)GetNodeData(list,list->length-1-i); } *(output+i)=0; return output; }
/* Add a node forward */ void AddNodeForward(void) { DoubleLinkedList* pNode = malloc(sizeof(DoubleLinkedList)); pNode = GetNodeData(pNode); if(pNode) { DoubleLinkedList* pCurrent = pHead; if (pHead== NULL) { pNode->pNext= NULL; pNode->pPrevious= NULL; pHead=pNode; } else { while(pCurrent->pNext!=NULL) { pCurrent=pCurrent->pNext; } pCurrent->pNext= pNode; pNode->pNext= NULL; pNode->pPrevious= pCurrent; } } else { Error = MEMALLOCERROR; } }
//将StringList中保存的所有字符串组合成为一个字符串 LPSTR StringListGetString(StringList list) { int i,j,k,size=0; LPSTR data; LPSTR String; for(i=0;i<list->length;i++){ data=(char*)GetNodeData(list,i); if(data==0)continue; size+=(int)strlen(data); } String=(char*)malloc(sizeof(char)*(size+1)); for(i=0,k=0;i<list->length;i++){ data=(char*)GetNodeData(list,i); if(data==0)continue; for(j=0;data[j]!=0;j++) { String[k++]=data[j]; } } String[k]=0; return String; }
void *NextNode(listPtr List) { if (List == NULL) return NULL; if (List->Current != NULL) List->Current = List->Current->Next; if ((List->Flags & LISTFLAGMASK) & LISTCIRCULAR) if (List->Current == NULL) List->Current = List->Head; return GetNodeData(List->Current); } /* NextNode() */
void *PrevNode(listPtr List) { if (List == NULL) return NULL; if (List->Current != NULL) List->Current = List->Current->Prev; if ((List->Flags & LISTFLAGMASK) & LISTCIRCULAR) if (List->Current == NULL) List->Current = List->Tail; return GetNodeData(List->Current); } /* PrevNode() */
int SplayInsertList(listPtr List, listnodePtr Node) { if (List == NULL) return LLIST_NULL; if (Node == NULL) return LLIST_NULL; if (List->Head != NULL) /* empty tree? */ { if (SplayList(List, Node->Data) != NULL) /* We found this element in the splay tree; this is bad. Say so... */ return LLIST_BADVALUE; if ((List->compare)(Node->Data, List->Head->Data) > 0) { Node->Prev = List->Head; if ((List->compare)(Node->Data, GetNodeData(List->Head->Next)) < 0) { Node->Next = List->Head->Next; List->Head->Next = NULL; } } else { Node->Next = List->Head; if ((List->compare)(Node->Data, GetNodeData(List->Head->Prev)) > 0) { Node->Prev = List->Head->Prev; List->Head->Prev = NULL; } } } List->Head = List->Current = Node; List->Size++; return LLIST_NOERROR; } /* SplayInsertList() */
void *IndexNode(listPtr List, int Index) { int Count; if ((List == NULL) || ((List->Flags & LISTFLAGMASK) & LISTBTREE)) return NULL; if (List->Size < Index) return NULL; List->Current = List->Head; for (Count = 1; Count < Index; Count++) List->Current = List->Current->Next; return GetNodeData(List->Current); } /* IndexNode() */
int DumpList(listPtr List, ListDumpFunc DataDump) /* Print List data using the DataDump function for Node Data Elements */ { int Count; listnodePtr Position; if (List == NULL) return LLIST_BADVALUE; Position = List->Current; List->Current = List->Head; for (Count = 1; Count <= List->Size; Count++) { DataDump(GetNodeData(List->Current)); NextNode(List); } List->Current = Position; return LLIST_NOERROR; }
int CZiMainFrame::OnClickVerifyResponse(WPARAM wp, LPARAM lp) { Assert(lp); VerifyScQuery_t * pVerifyq = (VerifyScQuery_t *)lp; VerifyCcResponse_t verifyp; if(wp == 1) { if(pVerifyq->nRecvType == Type_ImcFriend) { Assert(pVerifyq->pSenderNetQInfo && pVerifyq->pSenderNetQInfo->nItemType == Type_ImcFriend); CNodeList * pTeamInfo = GetTeamInfo(Team_DefaultNameT); Assert(pTeamInfo); if(pTeamInfo) { pVerifyq->pSenderNetQInfo->strAdminName = Team_DefaultNameA; AddItem(pVerifyq->pSenderNetQInfo, pTeamInfo); } } } // Msg_ScQueryVerify -> Msg_CsResponseVerify ..?? verifyp.bIsAgree = wp == 1 ? 1 : 0; verifyp.nSenderId = MagicId_t(Msg_CsResponseVerify, pVerifyq->nRecvType, pVerifyq->nRecverId); verifyp.nRecverId = MagicId_F(Msg_CsResponseVerify, pVerifyq->nSenderId); verifyp.szSenderName = pVerifyq->szRecverNamex; verifyp.szRecverName = pVerifyq->szSenderNamex; verifyp.nRecvType = pVerifyq->nRecvType; verifyp.pSenderLocalRInfo = GetNodeData(pVerifyq->nRecverId); Assert(m_pMainMsger); m_pMainMsger->SendImMessage(Msg_CsResponseVerify, (LPARAM)&verifyp, sizeof(verifyp)); m_pMainMsger->FreeDataEx(Msg_ScQueryVerify, pVerifyq); return 0; }
void AppendTail(List tails) { FILE *fp; int i; List writer = InitList(); Tail = hasTail ? Tail : Size; AddASCII(writer,IntToString(Tail)); AddASCII(writer," 0 obj\r\n<<"); Attr tail; for (i=0;i<tails->length;i++) { tail=(Attr)GetNodeData(tails,i); AddASCII(writer,"/"); AddASCII(writer,tail->Name); AddASCII(writer, "("); AddBigEndianUnicode(writer, tail->Value); AddASCII(writer,")"); } AddASCII(writer, ">>\r\nendobj"); if (hasTail) { if((fp=fopen(PDFPath,"wb"))==0) { printf("cannot open %s\n",PDFPath); system("pause"); exit(0); } int gap = writer->length - TailEnd + TailAt; //更新xrefs Xref xref; for (i = 0; i < xrefs->length; i++) { xref=(Xref)GetNodeData(xrefs,i); xref->newXrefOffset = xref->xrefOffset; xref->newPrev = xref->trailer->Prev; if (i > 0) { xref->newPrev = ((Xref)GetNodeData(xrefs,i-1))->newXrefOffset; } if (xref->xrefOffset > TailAt) //未检测位数变化 { xref->newXrefOffset += gap; } if (xref->trailer->XRefStm > TailAt) { xref->trailer->XRefStm += gap; } } int newStartxref = xref->newXrefOffset; List newXrefs=InitList(); int j,min,offset=0; Xref minOffsetXref; for(i=0;i<xrefs->length;i++)//鉴于xref不会很多,暂时用n^2的低效算法 { min=MAXINT; for(j=0;j<xrefs->length;j++) { xref=(Xref)GetNodeData(xrefs,j); if(xref->xrefOffset<=offset)continue; if(xref->xrefOffset<min){ min=xref->xrefOffset; minOffsetXref=xref; } } offset=minOffsetXref->xrefOffset; AddNode(newXrefs,minOffsetXref); } xrefs=newXrefs; int pos = 0; for(i=0;i<xrefs->length;i++) //pos确定Info在Xrefs的排位,指示在哪一个xref之前 { if (((Xref)GetNodeData(xrefs,i))->xrefOffset < TailAt) pos++; else break; } //重写到TailAt,思考能不能直接setlength!!! fwrite(PDFInByte,sizeof(char),TailAt,fp); //重写Tail fwrite(CharListGetString(writer),sizeof(char),writer->length,fp); //写Tail之后,xref之前 SaveXrefs(fp,TailEnd, gap, pos, xrefs->length, newStartxref,TailAt); } else { if((fp=fopen(PDFPath,"ab"))==0) { printf("cannot open %s\n",PDFPath); system("pause"); exit(0); } //写Tail前的\r\n fputs("\r\n",fp); fwrite(CharListGetString(writer),sizeof(char),writer->length,fp);//此处不能fputs!因为有特殊编码方式会被fputs认为是结束符,提前结束 TailAt = FileLength + 2;//+2因为Tail对象前面补充了\r\n TailEnd = TailAt + writer->length; Tail = Size; fputs("\r\nxref\r\n",fp); fputs(IntToString( Tail),fp); fputs(" 1\r\n",fp); for (i = 0; i < 10 - strlen(IntToString(TailAt)); i++){ fputs("0",fp); } fputs(IntToString(TailAt),fp); fputs(" 00000 n\r\ntrailer\r\n<</Size ",fp); fputs(IntToString(++Size),fp); fputs("/Root ",fp); fputs(IntToString(Root),fp); fputs(" 0 R/Info ",fp); fputs(IntToString(Info),fp); fputs( " 0 R/Prev ",fp); fputs(IntToString(StartXref),fp); fputs( "/Tail ",fp); fputs(IntToString(Tail),fp); fputs(" 0 R>>\r\nstartxref\r\n",fp); fputs(IntToString(TailEnd+2),fp); fputs( "\r\n%%EOF",fp);//writer此前保存的是Tail的信息,没有首尾的\r\n } fclose(fp); }
int SaveXrefs(FILE *fp, int index, int gap, int from, int to, int newStartxref,int boundary) { List writer = InitList(); LPSTR str = ""; int cursor,i,len; Xref xref; for (cursor = from; cursor < to; cursor++) { //xref之前 xref=(Xref)GetNodeData(xrefs,cursor); while (index < xref->xrefOffset) { fputc(PDFInByte[index++],fp); } //xref地址部分 while (PDFInByte[index] != 13 && PDFInByte[index] != 10) fputc(PDFInByte[index++],fp); while (PDFInByte[index] == 13 || PDFInByte[index] == 10) fputc(PDFInByte[index++],fp); len=xref->sections->length; Section sec; for (i=0;i<len;i++) { int count,j; sec=(Section)GetNodeData(xref->sections,i); while (PDFInByte[index] != 13 && PDFInByte[index] != 10) fputc(PDFInByte[index++],fp); while (PDFInByte[index] == 13 || PDFInByte[index] == 10) fputc(PDFInByte[index++],fp); for (count = 0; count < sec->count; count++) { char Addr[11]; for (j = 0; j < 10; j++) { Addr[j] = PDFInByte[index + j]; } Addr[j]=0; int num=IntParse(Addr); if (num > boundary) { num += gap; for (int j = 0; j < 10; j++) { Addr[9 - j] = num % 10 + 48; num /= 10; } } fputs(Addr,fp); index += 10; for (j = 0; j < 10; j++) { fputc(PDFInByte[index++],fp); } } } //trailer的处理 while (PDFInByte[index] != 62 || PDFInByte[index + 1] != 62) { if (PDFInByte[index] == 80 && PDFInByte[index + 1] == 114 && PDFInByte[index + 2] == 101 && PDFInByte[index + 3] == 118)//Prev { fputs("Prev ",fp); index +=(int)strlen("Prev "); str=IntToString(xref->newPrev); fputs(str,fp); index += (int)strlen(str); continue; } if (PDFInByte[index] == 88 && PDFInByte[index + 1] == 82 && PDFInByte[index + 2] == 101 && PDFInByte[index + 3] == 102)//XRef { writer=InitList(); int len = (int)strlen("XRefStm ")+(int)strlen(IntToString(xref->trailer->XRefStm)); index += len; fputs("DelTag ",fp); for (i = 0; i < len - 7; i++)fputc('0',fp); continue; } fputc(PDFInByte[index++],fp); }//结束时index指向>>的第一个> //看是否有startxref if (cursor == xrefs->length - 1) { int see = index + 2; while (PDFInByte[see] == 13 || PDFInByte[see] == 10) see++; //结束时指向下一行第一个字符 //若有start if (PDFInByte[see] == 115 && PDFInByte[see + 1] == 116 && PDFInByte[see + 2] == 97 && PDFInByte[see + 3] == 114 && PDFInByte[see + 4] == 116) { while (PDFInByte[see] < 48 || PDFInByte[see] > 57) see++;//see定位在第一个数字 while (index < see) fputc(PDFInByte[index++],fp);//结束时index指向第一个数字 str = IntToString(newStartxref); fputs(str,fp); index += (int)strlen(str); if (cursor == xrefs->length- 1) { while (index < FileLength) { fputc(PDFInByte[index++],fp); } break; } } } } return index; }
//读取PDF的信息 void ReadPath(char *PDFPath) { FILE *fp; if((fp=fopen(PDFPath,"rb"))==0) { printf("cannot open %s\n",PDFPath); } Title=L""; Author=L""; Subject=L""; Keywords=L""; CreationDate=L""; ModDate=L""; Creator=L""; Producer=L""; xrefs =InitList(); Tails=InitList(); Attrs=InitList(); FileLength=getFileSize(PDFPath); printf("FileLength: %d\n",FileLength); PDFInByte=(unsigned char*)malloc(sizeof(char)*FileLength); fread(PDFInByte,1,FileLength,fp); fclose(fp); Version[0]=PDFInByte[5]; Version[1]= '.' ; Version[2]=PDFInByte[7]; Version[3]=0; printf("Version: %s\n",Version); int index = FileLength; index = findStringUp(PDFInByte,FileLength,index, "%%EOF") - 5; while (PDFInByte[index] > 57 || PDFInByte[index] < 48) index--; int i = 1,j; StartXref = 0; while (PDFInByte[index] <= 57 && PDFInByte[index] >= 48) { StartXref += (PDFInByte[index--] - 48) * i; i *= 10; } printf("StartXref: %d\n",StartXref); ReadXref(StartXref); LPSTR* Addrs=(LPSTR*)malloc(sizeof(char*)*Size); Xref xref; Section section; for(i=0;i<xrefs->length;i++) { xref=(Xref)GetNodeData(xrefs,i); for(j=0;j< xref->sections->length;j++) { section=(Section)GetNodeData(xref->sections,j); for (int cursor = 0; cursor < section->count; cursor++) { Addrs[section->startID+cursor]=(LPSTR)GetNodeData(section->Addrs,cursor); //用新的覆盖旧的 } } } //读取Info if (Info == 0) return; index=InfoAt = IntParse(Substring(Addrs[Info],0, 10)); while (PDFInByte[index++] != 47) ; //找到第一个/,结束时index指向tag的第一个字符 List tag = InitList(); LPSTR tagString; LPWSTR valueString; valueString=(LPWSTR)malloc(sizeof(wchar_t)); while (PDFInByte[index] != 62)//> { //tag.Clear(); tag = InitList(); while (PDFInByte[index] != 32 && PDFInByte[index] != 40) //找到空格或者(,结束时index指向空格或( { AddNode(tag,(void*)PDFInByte[index]); index++; } index = omitBlank(PDFInByte,index); tagString =CharListGetString(tag); //开始读取value if (PDFInByte[index] != 40) //指向其他obj的情况 { int tagID = getNumber(PDFInByte, &index); index++; while (PDFInByte[index] != 47 && PDFInByte[index] != 62) index++; //找下一个/或者结束符>,结束时index指向下一个/或结束符> char *tagAddr = Substring(Addrs[tagID],0, 10); int cursor = IntParse(tagAddr); while (PDFInByte[cursor++] != 40) ; //找(,结束时指向属性的第一个字符 ReadValue(cursor,&valueString); } else //跟随的括号中有属性的情况 { index = ReadValue(++index, &valueString) + 1; //index此时指向)后面一个字符 while (PDFInByte[index] != 47 && PDFInByte[index] != 62) index++; //找下一个/或者结束符>,结束时index指向下一个/或结束符> } index++; //index最终定位在下一个tag的第一个字符或结束符> int TagNum=-1,i; for(i=0;i<8;i++) { if(strcmp(tagString,InfoTags[i])==0) { TagNum=i; break; } } switch (TagNum) { case 0: Title = valueString; break;//Title case 1: Author = valueString; break;//Author case 2: Subject = valueString; break;//Subject case 3: Keywords = valueString; break;//Keywords case 4: CreationDate = valueString; break; case 5: ModDate =valueString; break;//ModDate case 6: Creator = valueString; break;//Creator case 7: Producer = valueString; break;//Producer default: Attr attr=(Attr)malloc(sizeof(_Attr)); attr->Name=tagString; attr->Value=valueString; AddNode(Attrs,attr); break; } } while (PDFInByte[index] != 106) index++;//将index指向endobj的j InfoEnd = index + 1; //读取Tail if (Tail == 0) return; index=TailAt = IntParse(Substring(Addrs[Tail],0, 10)); while (PDFInByte[index++] != 47) ; //找到第一个/,结束时index指向tag的第一个字符 while (PDFInByte[index] != 62)//> { //tag.Clear(); tag=InitList(); while (PDFInByte[index] != 32 && PDFInByte[index] != 40) //找到空格或者(,结束时index指向空格或( { AddNode(tag,(void*)PDFInByte[index]); index++; } index = omitBlank(PDFInByte,index); tagString =CharListGetString(tag); //开始读取value,默认Tail的属性只以空号的形式保存 index = ReadValue(++index, &valueString) + 1; //index此时指向)后面一个字符 while (PDFInByte[index] != 47 && PDFInByte[index] != 62) index++; //找下一个/或者结束符>,结束时index指向下一个/或结束符> index++; //index最终定位在下一个tag的第一个字符或结束符> Attr tail=(Attr)malloc(sizeof(_Attr)); tail->Name=tagString; tail->Value=valueString; AddNode(Tails,tail); } while (PDFInByte[index] != 106) index++;//将index指向endobj的j TailEnd = index + 1; fclose(fp);//已经关闭过了? }
//保存Info和自定义属性 void SaveInfo(LPWSTR title, LPWSTR author, LPWSTR subject, LPWSTR keywords, List attrs) { FILE *fp; if((fp=fopen(PDFPath,"wb"))==0) { printf("cannot open %s\n",PDFPath); system("pause"); exit(0); } List writer = InitList(); LPSTR str; //生成新的Info AddASCII(writer, IntToString(Info)); AddASCII(writer, " 0 obj\r\n<</Title("); AddBigEndianUnicode(writer, title); AddASCII(writer, ")/Author("); AddBigEndianUnicode(writer, author); AddASCII(writer, ")/Subject("); AddBigEndianUnicode(writer, subject); AddASCII(writer, ")/Keywords("); AddBigEndianUnicode(writer, keywords); AddASCII(writer, ")/CreationDate("); AddASCII(writer, WCharToMByte(CreationDate)); AddASCII(writer, ")/ModDate("); AddASCII(writer, WCharToMByte(ModDate)); AddASCII(writer, ")/Creator("); AddBigEndianUnicode(writer, Creator); AddASCII(writer, ")/Producer("); AddBigEndianUnicode(writer, Producer); int i; Attr attr; for(i=0;i<attrs->length;i++) { attr=(Attr)GetNodeData(attrs,i); AddASCII(writer, ")/"); AddASCII(writer, attr->Name); AddASCII(writer, "("); AddBigEndianUnicode(writer, attr->Value); } AddASCII(writer, ")>>\r\nendobj"); int index = 0; int pointA = InfoAt; int pointB = InfoEnd; int gap = writer->length - pointB + pointA; //更新xrefs Xref xref; for (i = 0; i < xrefs->length; i++) { xref=(Xref)GetNodeData(xrefs,i); xref->newXrefOffset = xref->xrefOffset; xref->newPrev = xref->trailer->Prev; if (i > 0) { xref->newPrev = ((Xref)GetNodeData(xrefs,i-1))->newXrefOffset; } if (xref->xrefOffset > pointA) //未检测位数变化 { xref->newXrefOffset += gap; } if (xref->trailer->XRefStm > pointA) { xref->trailer->XRefStm += gap; } } int newStartxref = xref->newXrefOffset; List newXrefs=InitList(); int j,min,offset=0; Xref minOffsetXref; for(i=0;i<xrefs->length;i++)//鉴于xref不会很多,暂时用n^2的低效算法 { min=MAXINT; for(j=0;j<xrefs->length;j++) { xref=(Xref)GetNodeData(xrefs,j); if(xref->xrefOffset<=offset)continue; if(xref->xrefOffset<min){ min=xref->xrefOffset; minOffsetXref=xref; } } offset=minOffsetXref->xrefOffset; AddNode(newXrefs,minOffsetXref); } xrefs=newXrefs; int pos = 0; for(i=0;i<xrefs->length;i++) //pos确定Info在Xrefs的排位,指示在哪一个xref之前 { if (((Xref)GetNodeData(xrefs,i))->xrefOffset < pointA) pos++; else break; } index=SaveXrefs(fp, index, gap, 0, pos, newStartxref,InfoAt); //写到Info之前,此处不能fwrite因为起始点不为0 while (index < pointA) { fputc(PDFInByte[index++],fp); } //重写Info fwrite(CharListGetString(writer),sizeof(char),writer->length,fp); //写Info之后 index = pointB; index=SaveXrefs(fp,index, gap, pos, xrefs->length, newStartxref,InfoAt); fclose(fp); }