user-0 提问: 请问如何得到一个文件除去最后64位的部分。

回复:
user: user-1
content: 仅供且仅能参考： #include <sys\stat.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <string.h> #define MAX_CLU_BYTES 65536 FILE *fo; int fh; __int64 offs,offs1; __int64 rvi64; int rv,wrv; unsigned char buf[MAX_CLU_BYTES]; char ofn[_MAX_PATH]; char offstr[80]; void strcpybutcomma(char *t,char *s) {     char c;      while (1) {         c = *s++;         if (','!=c) *t++ = c;         if (0==c) break;     } } void main(int argc,char **argv) {     if (argc<3) {         printf("Copy File Tail.\n");         printf("Usage:\n");         printf("    cft filename.ext offset_begin[-offset_end]\n");         printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n");         printf("Note: Byte at offset_end is NOT included.\n");         printf("Example:\n");         printf("    cft abc.rar 12345\n");         printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");         printf("    cft abc.rar 123-12345\n");         printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");         printf("    cft abc.rar 0xAB-0xCD\n");         printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");         return;     }     strcpybutcomma(offstr,argv[2]);     rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);     if (rv==0) {         printf("offset %s is not number\n",argv[2]);         return;     }     fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYNO);     if (fh==-1) {         printf("_sopen %s errno=%d\n",argv[1],errno);         return;     }     if (rv==1) {         offs1=_filelengthi64(fh);         if (offs1==-1i64) {             printf("%I64=_filelengthi64 errno=%d\n",offs1,errno);             _close(fh);             return;         }     } else {//rv==2         if (offs1<offs) {             printf("%s offset_begin>offset_end error\n",argv[2]);             _close(fh);             return;         }     }     rvi64=_lseeki64(fh,offs,SEEK_SET);     if (rvi64!=offs) {         printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno);         _close(fh);         return;     }     sprintf(ofn,"%s-",offstr);     strcat(ofn,argv[1]);     fo=fopen(ofn,"wb");     if (fo==NULL) {         _close(fh);         printf("fopen %s error\n",ofn);         return;     }     cprintf("\n%I64u\r",offs);     while (1) {         rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));         if (rv==0) break;//         if (rv<0) {             fclose(fo);             _close(fh);             printf("_read %s offset %I64u error\n",argv[1],offs);             return;         }         wrv=fwrite(buf,1,rv,fo);         if (wrv!=rv) {             fclose(fo);             _close(fh);             printf("fwrite %s error\n",ofn);             return;         } else {             offs+=rv;             cprintf("%I64u\r",offs);             if (offs>=offs1) break;//         }     }     fclose(fo);     _close(fh);     printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn); }

user: user-0
content: 自问自答了，前面打开文件那里，用==比较了string，所以文件没有打开。

user: user-0
content: 引用 7 楼 Idle_ 的回复:[quote=引用 6 楼 u011336497 的回复:] [quote=引用 3 楼 Liu_peiqi 的回复:] 在c/c++程序中，约定俗成，n表大小，0->n-1表索引。 大神帮我看下为什么一个fseek都能出现segmentation fault。[/quote]  那就是有可能fseek前的语句中有溢出。检查一下前面grcp_xxxx传递的参数是否都正确[/quote] 可是把fseek注释掉就没问题了。

user: user-2
content: 引用 6 楼 u011336497 的回复:[quote=引用 3 楼 Liu_peiqi 的回复:] 在c/c++程序中，约定俗成，n表大小，0->n-1表索引。 大神帮我看下为什么一个fseek都能出现segmentation fault。[/quote]  那就是有可能fseek前的语句中有溢出。检查一下前面grcp_xxxx传递的参数是否都正确

user: user-0
content: 引用 3 楼 Liu_peiqi 的回复:在c/c++程序中，约定俗成，n表大小，0->n-1表索引。 大神帮我看下为什么一个fseek都能出现segmentation fault。

user: user-0
content: 引用 2 楼 robertbo 的回复:fseek是从0开始的，ftell得到的是n，比如fseek(fTmp, 100L, SEEK_SET);后，ftell大小得到的是（100-0）的值，所以是n。 大神帮我看下为什么一个fseek都能出现segmentation fault。

user: user-0
content: 引用 1 楼 user-5 的回复:是从0开始吧. 其实只要写一个程序跑一下就行了. 好郁闷，我fseek一下都segmentation fault.  #include <stdio.h> #include <stdlib.h> #include <gcrypt.h> void replace_newline(char *password, size_t length){ 	int i; 	for(i=0; i<length; i++){ 		if(password[i]=='\n'){ 			password[i]='\0'; 		} 	} }   void trim_filename(char *filename){ 	int i; 	for(i=0; i<30; i++){ 		if(filename[i]=='\0'){ 			filename[i-3]='\0'; 			break; 		} 	} } int main(int argc, char* argv[]){ 	if(argc<3){ 		printf("Please input enough parameters."); 	}     if(!gcry_check_version(GCRYPT_VERSION)){         fputs("libgcrypt version mismatch\n", stderr);         exit(2);     } 	/*Disable secure memory.*/ 	gcry_control(GCRYCTL_DISABLE_SECMEM, 0); 	/*Loading complete*/ 	gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 	printf("Initialization finished\n"); 	 	FILE *fp, *fpout; 	char *filename; 	char password[256]; 	char *salt="NaCl"; 	char key[64]; 	int initial_vector[4]={5, 8, 4, 4}; 	int filesize; 	char mac_buffer[64]; 	char mac_buffer_new[64]; 	int i; 	unsigned char cur; 	gcry_cipher_hd_t hd; 	gcry_md_hd_t hdmac; 	filename=argv[1]; 	if(argv[2]=="l"){ 		fp=fopen(argv[1],"r+"); 		trim_filename(filename); 		if(fp==NULL){ 			printf("Fail to open file."); 			exit(1); 		} 		 	}else{ //		receive_file(); 		fp=fopen("temp", "r"); 	}  	if(fopen(filename, "r")==NULL){ 		printf("File exists."); 		exit(33); 	}  	fpout=fopen(filename, "w"); 	 	printf("Password:"); 	fgets(password, 256, stdin); 	replace_newline(password, 256); 	gcry_kdf_derive(password, strlen(password), GCRY_KDF_PBKDF2, GCRY_MD_SHA512, salt, strlen(salt), 4096, 64, key); 	for(i=0; i<64; i++){ 		printf("%02X ", (unsigned char) key[i]); 	} 	printf("\n"); /*Get the last 64 bytes which is the HMAC. And verify it.*/ 	gcry_md_open(&hdmac, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC); 	gcry_md_setkey(hdmac, key, 64); 	fseek(fp, 0, SEEK_END); /*	filesize=ftell(fp); 	fseek(fp, 0L, SEEK_SET); 	 	fseek(fp, filesize-64, SEEK_SET); 	fread(mac_buffer, 64, 1, fp);//Get the last 64 bytes which is HMAC. 	fseek(fp, 0L, SEEK_SET); 	i=0; 	while(i<filesize-64){ 		cur=fgetc(fp); 		gcry_md_putc(hdmac, cur); 		i++; 	} 	mac_buffer_new=gcry_md_read(hdmac, GCRY_MD_SHA512); 	for(i=0; i<64; i++){ 		if(mac_buffer[i]!=mac_buffer_new[i]){ 			printf("HMAC doesn't match."); 		} 	} */      }

user: user-3
content: 在c/c++程序中，约定俗成，n表大小，0->n-1表索引。

user: user-4
content: fseek是从0开始的，ftell得到的是n，比如fseek(fTmp, 100L, SEEK_SET);后，ftell大小得到的是（100-0）的值，所以是n。

user: user-5
content: 是从0开始吧. 其实只要写一个程序跑一下就行了.