相同位置的重复文件指针
Duplicate File Pointer at the same position
大家好,
我有这个代码:
int lenInput;
char input[64], buffer[512], temp[512], *ret, tagName[] = "<name>", tagItem[] = "<item ";
bool deleted = false;
FILE *fp, *fpTemp = NULL;
if(! (fp = fopen(nameFile, "r+")) ) {
perror("Error Opening File");
exit(-1);
}
printf("Insert the Name of the service you want to erase... ");
fgets(input, sizeof(input), stdin);
lenInput = (int) strlen(input);
input[lenInput-1] = '[=10=]';
lenInput = (int) strlen(input);
do {
fgets(buffer, sizeof(buffer), fp);
buffer[strlen(buffer)-1] = '[=10=]';
if( (ret = strstr(buffer, tagName)) != NULL ) {
if( strncmp(ret, tagName, strlen(tagName)) == 0 ) {
if( (ret = strstr(ret, input)) != NULL ) {
if( strncmp(ret, input, lenInput) == 0 ) {
snprintf(temp, sizeof(temp), "<item present=\"false\">\n");
fputs(temp, fpTemp);
deleted = true;
}
}
}
}
else if( (ret = strstr(buffer, tagItem)) != NULL ) {
if( strncmp(ret, tagItem, strlen(tagItem)) == 0 ) {
fpTemp = fdopen( dup ( fileno(fp) ), "r+"); /* associates a stream with the existing file descriptor, fd */
}
}
} while( (deleted != true) && (!(feof(fp))) );
if(deleted == false)
printf("Error: Service Not Found!\n");
else
printf("Success: Service Erased!\n");
它可以处理这样的文件:
<serviceNumber>2</serviceNumber>
<item present="true">
<id>1</id>
<name>name1</name>
<description>descr1</description>
<x>1</x>
<y>1</y>
</item>
<item present="true">
<id>2</id>
<name>name2</name>
<description>descr2</description>
<x>2</x>
<y>2</y>
</item>
主文件指针 (FILE *fp
) 在 main()
.
我的想法是如果我找到标签 <item ...>
就复制文件指针 fp
(在原型中传递),因为如果这个标签链接到服务的名称我想擦除,我必须替换整个 <item ...>
字符串。
但是,我有一个问题...当我执行 snprintf()
和 fputs()
时,文件在文件开头被覆盖,因为恕我直言,我认为文件指针不重复。
有解决fix/resolve这个问题的方法或解决方法吗?
提前致谢!
您不需要复制文件指针,您需要使用ftell()
/ fseek()
。没有错误处理的小代码。 (所以请不要在没有通过检查returns添加错误处理的情况下复制它)。
FILE *f = fopen(f, "r");
// do various things with file
long where_am_i = ftell(f); // if it fails, -1 is returned and errno is set to indicate the error.
// Do stuff requiring moving cursor in f stream
fseek(f, SEEK_SET, where_am_i); // same returns convention as ftell()
// You moved cursor back, you can start reading again
此外,您似乎可以使用 fgetpos()
和 fsetpos()
。
大家好, 我有这个代码:
int lenInput;
char input[64], buffer[512], temp[512], *ret, tagName[] = "<name>", tagItem[] = "<item ";
bool deleted = false;
FILE *fp, *fpTemp = NULL;
if(! (fp = fopen(nameFile, "r+")) ) {
perror("Error Opening File");
exit(-1);
}
printf("Insert the Name of the service you want to erase... ");
fgets(input, sizeof(input), stdin);
lenInput = (int) strlen(input);
input[lenInput-1] = '[=10=]';
lenInput = (int) strlen(input);
do {
fgets(buffer, sizeof(buffer), fp);
buffer[strlen(buffer)-1] = '[=10=]';
if( (ret = strstr(buffer, tagName)) != NULL ) {
if( strncmp(ret, tagName, strlen(tagName)) == 0 ) {
if( (ret = strstr(ret, input)) != NULL ) {
if( strncmp(ret, input, lenInput) == 0 ) {
snprintf(temp, sizeof(temp), "<item present=\"false\">\n");
fputs(temp, fpTemp);
deleted = true;
}
}
}
}
else if( (ret = strstr(buffer, tagItem)) != NULL ) {
if( strncmp(ret, tagItem, strlen(tagItem)) == 0 ) {
fpTemp = fdopen( dup ( fileno(fp) ), "r+"); /* associates a stream with the existing file descriptor, fd */
}
}
} while( (deleted != true) && (!(feof(fp))) );
if(deleted == false)
printf("Error: Service Not Found!\n");
else
printf("Success: Service Erased!\n");
它可以处理这样的文件:
<serviceNumber>2</serviceNumber>
<item present="true">
<id>1</id>
<name>name1</name>
<description>descr1</description>
<x>1</x>
<y>1</y>
</item>
<item present="true">
<id>2</id>
<name>name2</name>
<description>descr2</description>
<x>2</x>
<y>2</y>
</item>
主文件指针 (FILE *fp
) 在 main()
.
我的想法是如果我找到标签 <item ...>
就复制文件指针 fp
(在原型中传递),因为如果这个标签链接到服务的名称我想擦除,我必须替换整个 <item ...>
字符串。
但是,我有一个问题...当我执行 snprintf()
和 fputs()
时,文件在文件开头被覆盖,因为恕我直言,我认为文件指针不重复。
有解决fix/resolve这个问题的方法或解决方法吗?
提前致谢!
您不需要复制文件指针,您需要使用ftell()
/ fseek()
。没有错误处理的小代码。 (所以请不要在没有通过检查returns添加错误处理的情况下复制它)。
FILE *f = fopen(f, "r");
// do various things with file
long where_am_i = ftell(f); // if it fails, -1 is returned and errno is set to indicate the error.
// Do stuff requiring moving cursor in f stream
fseek(f, SEEK_SET, where_am_i); // same returns convention as ftell()
// You moved cursor back, you can start reading again
此外,您似乎可以使用 fgetpos()
和 fsetpos()
。