user-0 提问: 文件中读写数据结构lseek之后出现问题？

回复:
user: user-1
content: 引用 楼主 linyimian7539 的回复:#include <string.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h>     #include <sys/stat.h>  typedef struct { 	int Id; 	int mathScore; 	int chScore; 	int enScore; 	int aveScore; 	char Name[32]; }STU;  int main() { 	STU stuInfo[2]; 	memset(stuInfo,0x00,sizeof(stuInfo)); 	 	int i; 	 	for(i=0; i<2; i++) 	{ 		printf("Please input one student's id name mathScore chScore enScore\n"); 		scanf("%d%d%d%d%s",&stuInfo[i].Id,&stuInfo[i].mathScore,&stuInfo[i].chScore,&stuInfo[i].enScore,&stuInfo[i].Name); 		stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3; 	} 	 	char *file = "f2.txt"; 	int fd = open(file,O_CREAT|O_WRONLY|O_APPEND,S_IREAD|S_IWRITE); 	 	int len = 0; 	for(i=0; i<2; i++) 	{ 		if(len = write(fd,&stuInfo[i],sizeof(stuInfo[i]))) 			printf("write len = %d\n",len); 	} 	close(fd); 	fd = open(file,O_CREAT|O_RDONLY,S_IREAD); 	//len = lseek(fd,0,SEEK_SET); 	//printf("lseek len = %d\n",len); 	memset(stuInfo,0x00,sizeof(stuInfo)); 	for(i=0; i<2; i++) 	{ 		if(len = read(fd,&stuInfo[i],sizeof(stuInfo[i]))) 			printf("read len = %d\n",len); 	} 	 	for(i=0; i<2; i++) 	{ 		stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3; 		printf("%d %s %d %d %d %d\n",stuInfo[i].Id,stuInfo[i].Name,stuInfo[i].mathScore,stuInfo[i].chScore,stuInfo[i].enScore,stuInfo[i].aveScore); 	} 	 	return 0; 	 } 上面是把一个数据结构写到文件中再读出来，这样是没问题的，但是如果把close(fd); 	fd = open(file,O_CREAT|O_RDONLY,S_IREAD);注释掉，将//len = lseek(fd,0,SEEK_SET); 	//printf("lseek len = %d\n",len);注释去掉之后，read的结果是-1，读不出来数据，请问大神这是什么问题，环境是在centos环境下编译运行。  除楼上们所说， 附一点： 学习最根本的东西才能降低下次犯错的可能性： http://blog.csdn.net/liigo/article/details/582231/ 或 baidu gdb调试

user: user-2
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-3
content: #include <string.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>  typedef struct {     int Id;     int mathScore;     int chScore;     int enScore;     int aveScore;     char Name[32]; }STU;  int main() {     STU stuInfo[2];     memset(stuInfo,0x00,sizeof(stuInfo));      int i;      for(i=0; i<2; i++)     {         printf("Please input one student's id name mathScore chScore enScore\n");         scanf("%d%d%d%d%s",                 &stuInfo[i].Id,                 &stuInfo[i].mathScore,                 &stuInfo[i].chScore,                 &stuInfo[i].enScore,                 stuInfo[i].Name);         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;     }      char *file = "f2.txt";     int fd = open(file,O_CREAT|O_WRONLY|O_APPEND,S_IREAD|S_IWRITE);      int len = 0;     for(i=0; i<2; i++)     {         if((len = write(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("write len = %d\n",len);     }     close(fd);     fd = open(file,O_CREAT|O_RDONLY,S_IREAD);     len = lseek(fd,0,SEEK_SET);     printf("lseek len = %d\n",len);     memset(stuInfo,0x00,sizeof(stuInfo));     for(i=0; i<2; i++)     {         if((len = read(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("read len = %d\n",len);     }      for(i=0; i<2; i++)     {         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;         printf("%d %s %d %d %d %d\n", stuInfo[i].Id,stuInfo[i].Name,                 stuInfo[i].mathScore,stuInfo[i].chScore,                 stuInfo[i].enScore,stuInfo[i].aveScore);     }      return 0;  } 代码没什么问题，注释那两行和不注释都没问题。再说，注释的那两行不会影响读写。如果把close(fd)注释掉，那么第二次打开去读时可能读不到数据，因为写入的数据还在内存中，不在文件中，所以不能把写入之后的close(fd)注释掉； 注意，你的写入之前的键盘输入时，提示信息是id name xxx xxx xxx但是，实际上name是最要求最后输入的，所以这是一个问题～很容易输错。

user: user-4
content: 已更新方式打开一个文件同时进行读写, 读写切换时需要调用干预函数fseek(), fsetpos(), or rewind()来重置文件指针位置. http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html When a file is opened with update mode ( '+' as the second or third character in the mode argument), both input and output may be performed on the associated stream.  However, the application shall ensure that output is not directly followed by input without an intervening call to fflush() or to a file positioning function (fseek(), fsetpos(), or rewind()), and input is not directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

user: user-5

user: user-5
content: 来个人看看呐

user: user-5
content: 引用 10 楼 linyimian7539 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] #include <string.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>  typedef struct {     int Id;     int mathScore;     int chScore;     int enScore;     int aveScore;     char Name[32]; }STU;  int main() {     STU stuInfo[2];     memset(stuInfo,0x00,sizeof(stuInfo));      int i;      for(i=0; i<2; i++)     {         printf("Please input one student's id name mathScore chScore enScore\n");         scanf("%d%d%d%d%s",                 &stuInfo[i].Id,                 &stuInfo[i].mathScore,                 &stuInfo[i].chScore,                 &stuInfo[i].enScore,                 stuInfo[i].Name);         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;     }      char *file = "f2.txt";     int fd = open(file,O_CREAT|O_WRONLY|O_APPEND,S_IREAD|S_IWRITE);      int len = 0;     for(i=0; i<2; i++)     {         if((len = write(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("write len = %d\n",len);     }     close(fd);     fd = open(file,O_CREAT|O_RDONLY,S_IREAD);     len = lseek(fd,0,SEEK_SET);     printf("lseek len = %d\n",len);     memset(stuInfo,0x00,sizeof(stuInfo));     for(i=0; i<2; i++)     {         if((len = read(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("read len = %d\n",len);     }      for(i=0; i<2; i++)     {         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;         printf("%d %s %d %d %d %d\n", stuInfo[i].Id,stuInfo[i].Name,                 stuInfo[i].mathScore,stuInfo[i].chScore,                 stuInfo[i].enScore,stuInfo[i].aveScore);     }      return 0;  } 代码没什么问题，注释那两行和不注释都没问题。再说，注释的那两行不会影响读写。如果把close(fd)注释掉，那么第二次打开去读时可能读不到数据，因为写入的数据还在内存中，不在文件中，所以不能把写入之后的close(fd)注释掉； 注意，你的写入之前的键盘输入时，提示信息是id name xxx xxx xxx但是，实际上name是最要求最后输入的，所以这是一个问题～很容易输错。  找到错误原因了，open的时候flag标识有问题O_WRONLY，在write之后把文件close然后再open不会出问题，但是如果把37,38行注释掉，39,40行的注释去掉，因为文件描述符标识为O_WRONLY，所以read的时候就有问题了，改为O_RDWR之后解决。[/quote] 改正，代码应该是41,42以及42,43两行

user: user-5
content: 引用 5 楼 cfjtaishan 的回复:#include <string.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>  typedef struct {     int Id;     int mathScore;     int chScore;     int enScore;     int aveScore;     char Name[32]; }STU;  int main() {     STU stuInfo[2];     memset(stuInfo,0x00,sizeof(stuInfo));      int i;      for(i=0; i<2; i++)     {         printf("Please input one student's id name mathScore chScore enScore\n");         scanf("%d%d%d%d%s",                 &stuInfo[i].Id,                 &stuInfo[i].mathScore,                 &stuInfo[i].chScore,                 &stuInfo[i].enScore,                 stuInfo[i].Name);         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;     }      char *file = "f2.txt";     int fd = open(file,O_CREAT|O_WRONLY|O_APPEND,S_IREAD|S_IWRITE);      int len = 0;     for(i=0; i<2; i++)     {         if((len = write(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("write len = %d\n",len);     }     close(fd);     fd = open(file,O_CREAT|O_RDONLY,S_IREAD);     len = lseek(fd,0,SEEK_SET);     printf("lseek len = %d\n",len);     memset(stuInfo,0x00,sizeof(stuInfo));     for(i=0; i<2; i++)     {         if((len = read(fd,&stuInfo[i],sizeof(stuInfo[i]))) > 0)             printf("read len = %d\n",len);     }      for(i=0; i<2; i++)     {         stuInfo[i].aveScore = (stuInfo[i].mathScore+stuInfo[i].chScore+stuInfo[i].enScore)/3;         printf("%d %s %d %d %d %d\n", stuInfo[i].Id,stuInfo[i].Name,                 stuInfo[i].mathScore,stuInfo[i].chScore,                 stuInfo[i].enScore,stuInfo[i].aveScore);     }      return 0;  } 代码没什么问题，注释那两行和不注释都没问题。再说，注释的那两行不会影响读写。如果把close(fd)注释掉，那么第二次打开去读时可能读不到数据，因为写入的数据还在内存中，不在文件中，所以不能把写入之后的close(fd)注释掉； 注意，你的写入之前的键盘输入时，提示信息是id name xxx xxx xxx但是，实际上name是最要求最后输入的，所以这是一个问题～很容易输错。  找到错误原因了，open的时候flag标识有问题O_WRONLY，在write之后把文件close然后再open不会出问题，但是如果把37,38行注释掉，39,40行的注释去掉，因为文件描述符标识为O_WRONLY，所以read的时候就有问题了，改为O_RDWR之后解决。

user: user-5
content: 引用 8 楼 wyyy2088511 的回复:直接调用write并没有写到文件中，可以在debug 中查看，文件没有数据，直接读数据当然读不出来数据，write后frush 才会有数据！ 你说的应该是fopen等库函数，有缓存的。

user: user-6
content: 直接调用write并没有写到文件中，可以在debug 中查看，文件没有数据，直接读数据当然读不出来数据，write后frush 才会有数据！