user-0 提问: c语言文件操作

回复:
user: user-1
content: 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  英语也是一门计算机语言的说。

user: user-1
content: _chdir, _wchdir Change the current working directory.  int _chdir( const char *dirname );  int _wchdir( const wchar_t *dirname );  Routine Required Header Optional Headers Compatibility  _chdir <direct.h> <errno.h> Win 95, Win NT  _wchdir <direct.h> or <wchar.h> <errno.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a value of 0 if successful. A return value of –1 indicates that the specified path could not be found, in which case errno is set to ENOENT.  Parameter  dirname  Path of new working directory  Remarks  The _chdir function changes the current working directory to the directory specified by dirname. The dirname parameter must refer to an existing directory. This function can change the current working directory on any drive and if a new drive letter is specified in dirname, the default drive letter will be changed as well. For example, if A is the default drive letter and \BIN is the current working directory, the following call changes the current working directory for drive C and establishes C as the new default drive:  _chdir("c:\\temp");  When you use the optional backslash character (\) in paths, you must place two backslashes (\\) in a C string literal to represent a single backslash (\).  _wchdir is a wide-character version of _chdir; the dirname argument to _wchdir is a wide-character string. _wchdir and _chdir behave identically otherwise.  Generic-Text Routine Mapping:  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tchdir _chdir _chdir _wchdir    Example  /* CHGDIR.C: This program uses the _chdir function to verify  * that a given directory exists.  */  #include <direct.h> #include <stdio.h> #include <stdlib.h>  void main( int argc, char *argv[] ) {    if( _chdir( argv[1] )   )       printf( "Unable to locate the directory: %s\n", argv[1] );    else       system( "dir *.wri"); }   Output   Volume in drive C is CDRIVE  Volume Serial Number is 0E17-1702   Directory of C:\write  04/21/95  01:06p                 3,200 ERRATA.WRI 04/21/95  01:06p                 2,816 README.WRI                2 File(s)          6,016 bytes                              71,432,116 bytes free   Directory Control Routines  See Also   _mkdir, _rmdir, system

user: user-1
content: _getcwd, _wgetcwd Get the current working directory.  char *_getcwd( char *buffer, int maxlen );  wchar_t *_wgetcwd( wchar_t *buffer, int maxlen );  Routine Required Header Compatibility  _getcwd <direct.h> Win 95, Win NT  _wgetcwd <direct.h> or <wchar.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a pointer to buffer. A NULL return value indicates an error, and errno is set either to ENOMEM, indicating that there is insufficient memory to allocate maxlen bytes (when a NULL argument is given as buffer), or to ERANGE, indicating that the path is longer than maxlen characters.  Parameters  buffer  Storage location for path  maxlen  Maximum length of path in characters: char for _getcwd and wchar_t for _wgetcwd  Remarks  The _getcwd function gets the full path of the current working directory for the default drive and stores it at buffer. The integer argument maxlen specifies the maximum length for the path. An error occurs if the length of the path (including the terminating null character) exceeds maxlen. The buffer argument can be NULL; a buffer of at least size maxlen (more only if necessary) will automatically be allocated, using malloc, to store the path. This buffer can later be freed by calling free and passing it the _getcwd return value (a pointer to the allocated buffer).  _getcwd returns a string that represents the path of the current working directory. If the current working directory is the root, the string ends with a backslash ( \ ). If the current working directory is a directory other than the root, the string ends with the directory name and not with a backslash.  _wgetcwd is a wide-character version of _getcwd; the buffer argument and return value of _wgetcwd are wide-character strings. _wgetcwd and _getcwd behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tgetcwd _getcwd _getcwd _wgetcwd    Example  // GETCWD.C /* This program places the name of the current directory in the   * buffer array, then displays the name of the current directory   * on the screen. Specifying a length of _MAX_PATH leaves room   * for the longest legal path name.  */  #include <direct.h> #include <stdlib.h> #include <stdio.h>  void main( void ) {    char buffer[_MAX_PATH];     /* Get the current working directory: */    if( _getcwd( buffer, _MAX_PATH ) == NULL )       perror( "_getcwd error" );    else       printf( "%s\n", buffer ); }   Output  C:\code   Directory Control Routines  See Also   _chdir, _mkdir, _rmdir

user: user-0
content: 虽然不明白感觉好高大上的样子，可以翻译一下么

user: user-0
content: 引用 7 楼 sietlkj0811 的回复:文件写入函数未必表示当场写入，有可能只是记住了要写入的内容，等收到刷新指令的时候才正式写入。退出软件时操作系统会自动帮你把文件关闭，文件关闭前会发刷新指令，你要想马上看到写入，除了关闭文件外，可以调用flush函数，具体函数名查一下，我记得是叫FLUSH 我没用fclose，直接关闭控制台，然后重新打开程序，发现之前写的文件的数据并没有保存啊

user: user-2
content: 文件写入函数未必表示当场写入，有可能只是记住了要写入的内容，等收到刷新指令的时候才正式写入。退出软件时操作系统会自动帮你把文件关闭，文件关闭前会发刷新指令，你要想马上看到写入，除了关闭文件外，可以调用flush函数，具体函数名查一下，我记得是叫FLUSH

user: user-3
content: 最后加上fclose

user: user-0
content: 楼上代码有很多没用的部分， 代码作用是，输入软件名，和地址，打开它， 出问题的代码是，将楼上的代码  main函数中文件打开剪切到循环中。 g_judge(char k)判断函数每次调用都会使结构体数据的weight+1.写入到文件中 然后，问题是，+1后的值没有保存

user: user-0
content: /************************************************ *author：	jdz *data：		2016.10.？ *explain：	打算做一个类似数据库的系统，可以打开软件，记录东西。 * *ver： *		2016.10.18--学习了文件打开方式，对于w，r，a 和+的打开方式 *					学习了fseek()定位，随机读取文件 *					了解了feof()函数，使用条件 *					读写失败，打开失败，大多是由于文件不存在，数据不存在导致的。 *		2016.10.19--添加了修改功能，准备 ***************************************************/  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h>  /************全局变量********************/  FILE *fp; char *f_name;//文件名 long num;//文件记录条数  long m_tree;//命令树层数  0为初始化，1高2低 long m_n; //某节点下，命令序号  /***************************************/  /*****************全局结构体********************/ typedef struct address{ 	char explain[20]; 	char addr[100]; 	int	 n;//序号，从1开始 	int	 weight; }addr;  /*********************************************/   /******************时间函数******************************** * * *******************************************************/ void Time_Init() { 	time_t t1; 	struct tm *t2; 	 	t1 = time(NULL); 	t2 = localtime(&t1); 	if((fp = fopen(f_name,"rb+")) == NULL) 	{	  		if((fp = fopen(f_name,"wb+")) == NULL) 		{ 			printf("file open error!"); 			exit(0); 		} 		num = 0; 		if((fwrite(&t1,sizeof(long),1,fp)) == NULL)//当前时间 		{ 			printf("write 1 error!"); 			//exit(0); 		}	 		if((fwrite(&t1,sizeof(long),1,fp)) == NULL)//上一次时间 		{ 			printf("write 2 error!"); 			//exit(0); 		} 		if((fwrite(&num,sizeof(long),1,fp)) == NULL)//记录条数 		{ 			printf("write 2 error!"); 			//exit(0); 		}	 	} 	else 	{ 		if((fwrite(&t1,sizeof(long),1,fp)) == NULL) 		{ 			printf("write 1 error!"); 			 		} 		fseek(fp,2*sizeof(long),0); 		if((fread(&num,sizeof(long),1,fp)) == NULL) 		{ 		printf(" judge read error!"); 		} 		 	}	 	fclose(fp); 	fp = NULL;  	printf("\n%d年%d月%d日%d\:%d:%d\n",1900+t2->tm_year,1+t2->tm_mon,t2->tm_mday,t2->tm_hour,t2->tm_min,t2->tm_sec); 	printf("num is %d\n",num); } /******************************************************************************************************/ #define  g_menu 	printf("\n按下r键返回上一级-----");\ 					if(ct)\ 					{\ 						for( ; (i < 5)&&(i < num); i++) \ 						{ \ 							if((fread(&tmp,sizeof(addr),1,fp)) == NULL) \ 							{ \ 								printf("menu read error!"); \ 							} \ 							else \ 							{ \ 								printf("\n\t%d\t%s",i,tmp.explain); \ 							} 	\ 						} \ 					}\ 						printf("\n按c键继续————"); \ 						scanf("%s",&k); /*******************判断***************************/ int g_judge(char k) { 	int i = 0; 	int n; 	addr tmp2; 	n = atoi(&k); 	fseek(fp,3*sizeof(long),0); 	fseek(fp,n*sizeof(addr),1); 	if((fread(&tmp2,sizeof(addr),1,fp)) == NULL) 	{ 		printf(" judge read error!"); 	} 	printf("%s",tmp2.addr); 	tmp2.weight =tmp2.weight + 1; 	fseek(fp,(-1)*sizeof(addr),1); 	if((fwrite(&tmp2,sizeof(addr),1,fp)) == NULL) 	{ 		printf("write error!"); 	} 	printf("\nseccess!"); 	system(tmp2.addr); 	return 0;  }  /*******************插入***************************/ void g_insert(int n) { 	addr tmp;  	printf("请输入命令："); 	scanf("%s",tmp.explain); 	printf("请输入地址："); 	scanf("%s",tmp.addr); 	tmp.weight = 0; 	tmp.n = n;  	if((fwrite(&tmp,sizeof(addr),1,fp)) == NULL) 		{ 			printf("write error!"); 		}  	num = num + 1; 	fseek(fp,2L*sizeof(long),0); 	if((fwrite(&num,sizeof(long),1,fp)) == NULL) 	{ 		printf("write 3 error!"); 			 	} 	printf("insert  seccess\n"); 	fclose(fp); 	fp = NULL; 	getchar(); } /* void g_insert(int n) { 	addr tmp;  	if((fp = fopen(f_name,"rb+")) == NULL) 	{ 		printf("file open error!"); 	} 	printf("请输入命令："); 	scanf("%s",tmp.explain); 	printf("请输入地址："); 	scanf("%s",tmp.addr); 	tmp.weight = 0; 	tmp.n = 0; 	 	fseek(fp,0L,2); 	if((fwrite(&tmp,sizeof(addr),1,fp)) == NULL) 		{ 			printf("write error!"); 		} 	//num = num + 1; 	fseek(fp,2L*sizeof(long),0); 	if((fwrite(&num,sizeof(long),1,fp)) == NULL) 	{ 		printf("write 3 error!"); 			 	} 	printf("insert  seccess\n"); 	fclose(fp); 	fp = NULL; 	getchar(); } */ /*****************交换排序**************************************/ void g_sort() { 	fseek(fp,3*sizeof(long),0); 	 } /******************查找定位****************************************/ int g_search( ) { 	//#define IS_SAME strcmp(pt,tmp.explain) == 0 	 	int i = 0; 	int n; 	//int flag = 0; 	addr tmp;  	/*****************显示所有记录***************************************/ 	fseek(fp,3*sizeof(long),0); 	printf("\n**************************\n"); 	for(i = 0; i < num; i++) 	{ 		if((fread(&tmp,sizeof(addr),1,fp)) == NULL) 		{ 			printf(" judge read error!"); 		} 		printf("\n*%d*\texplain:%s",tmp.n,tmp.explain); 		printf("\n\taddr___%s\t",tmp.addr);  	} 	printf("\n请输入操作的记录序号："); 	scanf("%d",&n); 	return n;  	/************************************************************************/ 	/* 	do{ 		if((fread(&tmp,sizeof(addr),1,fp)) == NULL) 		{ 			printf(" judge read error!"); 		} 		if(feof(fp)) 		{ 			flag = -1; 			break; 		} 	}while (IS_SAME); 	 	return flag; 	*/ } /******************删除和修改****************************************/ void g_dam(char p) { 	addr tmp; 	if( p == 'd') 	{ 		fseek(fp, sizeof(addr),1); 	} 	else if(p == 'm') 	{ 		fseek(fp,sizeof(addr),1); 		printf("请输入命令："); 		scanf("%s",tmp.explain); 		printf("请输入地址："); 		scanf("%s",tmp.addr); 		printf("请输入权重："); 		scanf("%d",&tmp.weight);   	}  	 } /***********************************************************/ void g_modify() { #define MODIFY  (n < num )&&(n > 0) #define INSERT  (n == (num+1)) 	int n; 	addr tmp;  	n = g_search(); 	fseek(fp,3*sizeof(long),0); 	fseek(fp,(n-1)*sizeof(addr),1); 	 	if(MODIFY) 	{ 		printf("请输入命令："); 		scanf("%s",tmp.explain); 		printf("请输入地址："); 		scanf("%s",tmp.addr); 		printf("%d",tmp.weight); 		tmp.n = n; 		if((fwrite(&tmp,sizeof(addr),1,fp)) == NULL) 		{ 		printf("write error!"); 		} 	} 	else if(INSERT) 	{ 		g_insert(n); 	} 	else 	{ 		printf("禁止操作！"); 	} } /************************显示命令信息**********************************/ void g_showonwcmd() { 	int n; 	addr tmp;  	n = g_search( ); 	fseek(fp,3*sizeof(long),0); 	fseek(fp,(n-1)*sizeof(addr),1); 	if((fread(&tmp,sizeof(addr),1,fp)) == NULL) 	{ 		printf(" judge read error!"); 	} 	printf("\n*%d*\texplain:%s",tmp.n,tmp.explain); 	printf("\n\taddr___%s\t",tmp.addr); 	printf("\n\tweight__%d",tmp.weight); } /*******************************************************/ void g_op() { 	#define ct (num != 0)&&(i <= num) 	int i = 0;//循环计数 	char k; 	addr tmp; 	/*************打开文件*************************/  	fseek(fp,3*sizeof(long),0); //定位  	/*************************** 	*默认进入三级菜单 	*三级菜单 	****************************/  	printf("请输入相应数字选择操作"); 	g_menu 	switch(k) 	{ 		case 'c':     //继续显示可选项 			m_tree = 3; 			g_menu 				break; 		case 'r':    //返回到二级菜单 			m_tree = 2; 				break; 		//case 3: 		//case 4: 		default: 				if(g_judge(k) == -1) 				{ 					printf("not search"); 				} 				m_tree = 3; 			break; 		} /*******************************************************/ 	/************************* 	*二级菜单 	****************************/ 	if(m_tree == 2) 	{ 		system("cls"); 		printf("----------------------------------------------------"); 		printf("\n\t*0*\t退出程序"); 		printf("\n\t*1*\t增加一条命令"); 		printf("\n\t*2*\t修改一条命令"); 		printf("\n\t*3*\t显示一条命令"); 	 		//printf("\n\t*2*\t删除一条命令"); 		printf("\n----------------------------------------------------\n"); 		scanf("%d",&m_n); 		switch(m_n) 		{ 		case 0: 			exit(0); 		case 1: 			g_modify(); 			break; 		case 2: 			g_modify(); 		case 3: 			g_showonwcmd(); 		default: 			break;  		} 	} }   int main() { 	char g_f[]= "f_general"; 	m_tree = 0; //命令树层数初始化 	f_name = g_f; 	Time_Init(); 	if((fp = fopen(f_name,"rb+")) == NULL) 	{ 		printf("file open error!"); 	} 	while(1) 	{ 	g_op(); 	} 	return 0; } /*D:\\user_program\\QQ\\Bin\\QQScLauncher.exe  */

user: user-0
content: [ 引用 2 楼 user-4 的回复:lz最好给出测试代码, 不过注意的是, fread返回的类型是size_t, C语言中，可能会将NULL定义为(void*)0, 直接与0判断即可 然而我的代码好多啊，刚自己打算写一个的但是没有成功

user: user-4
content: lz最好给出测试代码, 不过注意的是, fread返回的类型是size_t, C语言中，可能会将NULL定义为(void*)0, 直接与0判断即可

user: user-0
content: c语言渣渣，如有幼稚言论，请谅解