!50分求解:在文件中以ASCII码写入的数字在进行小数字覆盖大数字时,如何删去多出来的字节?
我的情况是:文件内容如下描述:
# file begin
export THISVAL=2147483645
THISVAL可以递增从1变到2147483647,当超过2147483647时要求将被原成为1。
现在我写了程序来实现这个功能,用fprintf函数来做ASCII格式的写入。但是发现当还原成1时,情况变成了:
# file begin
export THISVAL=1147483647
只有1把2147483647中的第一个字节的数字2给替换掉了,而剩下的字节没有被消除掉。
请问各位,应该怎么样才能避免这样的情况,而得到正确的结果呢?
我的代码如下:
#include <stdlib.h>
#include <stdio.h>
int main()
{
FILE *fp;
char buf[20]={0};
int pos=0;// 'pos ' will record the offset in buffer comes from file
int i=0;
char* lrsn = "2147483645 ";
long tmp_lrsn = atol(lrsn);// char * --> long int
printf( "char lrsn is %s, and the long lrsn is %ld\n ", lrsn, tmp_lrsn);
fp = fopen( "lrsn.txt ", "r+ ");
fseek(fp, -20, SEEK_END);// read 10 bytes from EOF
fgets(buf, 20, fp);
while(i <20)
{
if( buf[i] == 61 )// find "= "
{
pos = i;
printf( "find '= ' !!! i=%d, pos=%d\n ", i, pos);
break;
}
if( buf[i] ==10 )// find '\n '
{printf( "find Enter! now the i is %d!! ", i); }
printf( "%c %d ", buf[i], buf[i]);
i++;
}
fseek(fp, -20, SEEK_END);// re-do allocation
for(i = 0; i <2; i++ )
{
// count lrsn 's value
tmp_lrsn++;
if( tmp_lrsn < 2147483647 )
{
fseek(fp, pos+1, SEEK_CUR);
fprintf(fp, "%ld ", tmp_lrsn);
if( tmp_lrsn < 10 )
fseek(fp, -(pos+2), SEEK_CUR);
else if( tmp_lrsn < 100 )
fseek(fp, -(pos+2+1), SEEK_CUR);
else if( tmp_lrsn < 1000 )
fseek(fp, -(pos+2+2), SEEK_CUR);
else if( tmp_lrsn < 10000 )
fseek(fp, -(pos+2+3), SEEK_CUR);
else if( tmp_lrsn < 100000 )
fseek(fp, -(pos+2+4), SEEK_CUR);
else if( tmp_lrsn < 1000000 )
fseek(fp, -(pos+2+5), SEEK_CUR);
else if( tmp_lrsn < 10000000 )
fseek(fp, -(pos+2+6), SEEK_CUR);
else if( tmp_lrsn < 100000000 )
fseek(fp, -(pos+2+7), SEEK_CUR);
else if( tmp_lrsn < 1000000000 )
fseek(fp, -(pos+2+8), SEEK_CUR);
else
fseek(fp, -(pos+2+9), SEEK_CUR);
}
else if( tmp_lrsn > = 2147483647 )
{
tmp_lrsn = 1;
fseek(fp, pos+1, SEEK_CUR);
fprintf(fp, "%ld ", tmp_lrsn);
fseek(fp, -(pos+2), SEEK_CUR);
}
}
fclose(fp);
return 0;
}
另外第二个问题是,如果我的文件还有个结尾描述的话,应该怎么办呢?如下所示:
# file begin
export THISVAL=1147483647
#eof
多了最后一行的话,我该如何处理?
[解决办法]
export THISVAL=2147483645
无论原来的文件内容 THISVAL=??
先在 = 字符后面写10个空格字符,覆盖掉原来的所有数字,
然后再在 = 号后面写上新的数值
[解决办法]
很遗憾流方式文件处理没有修改文件大小的函数.低级方式文件处理(open-close-lseek-read-wirte)倒可以用chsize(int handle, long size )来完成.因此你可以用如下处理:
int main()
{
...
fclose(fp);
int file_len = //... 计算好所需文件长度
MyChangeFileSize( "lrsn.txt ", file_len);
}
void MyChangeFileSize(const char *cszFileName, int nLen)
{
int fd = open(cszFileName, O_RDWR|O_BINARY);
chsize(fd, nLen);
close(fd);
}
[解决办法]
行读取, 更改行, 写到新文件
其他的方法会带来很多麻烦, 速度又慢
实在不行, 你可以memmove, fflush?