c语言 - 删除标签的内容<img></img>



我有这个代码。代码的目的是打印<img>之前的所有内容以及</img>之后的所有内容。不应打印<img></img>之间的所有内容。但是,我有 2 个问题。

  1. 代码正在Windows(gcc编译器(上编译,但是当我运行它时,它只是说"程序停止工作"?
  2. 代码正在打印所有内容。它甚至正在打印<img></img>以及介于两者之间的一切。

我 #includes:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>

法典:

void replacer_and_print(FILE *fp) {
char* line;
size_t len;
ssize_t read;
bool found_tag = false;
int line_storer;
char* before_tag;
char* after_tag;
while ((read = getline(&line, &len, fp)) != -1) {
if (
((before_tag = strstr(line, "<img>")) != NULL) &&
((after_tag = strstr(line, "</img>")) != NULL)
) {   
line_storer = before_tag - line; 
printf("%.*s", line_storer, line);
printf("The Image use to be heren");
line_storer = after_tag - line + strlen("</img>"); 
printf("%s", line + line_storer);
} else if ((before_tag = strstr(line, "<img>")) != NULL) {
line_storer = before_tag - line; 
printf("%.*s", line_storer, line);
found_tag = true;
} else if((after_tag = strstr(line, "</img>")) != NULL) {
found_tag = false;
line_storer = after_tag - line + strlen("</img>"); 
printf("%s", line + line_storer);
} else if(!found_tag) {
printf("%s", line);
}
}
fclose(fp);
}

测试.html:

<b>This is a test page</b>
<div class=back1>Some more text here for more testing!!!!</div>
<img>www.website.com/image.png</img>
<i>More words</i>
<u><i><b>TESTING 123</u></i></b>

输出:

<b>This is a test page</b>
<div class=back1>Some more text here for more testing!!!!</div>
The Image use to be here
<i>More words</i>
<u><i><b>TESTING 123</u></i></b>

假设:

There will only be one <img>
There will only be one </img>. The </img> tag will always be after the <img>

您需要在首次调用getline()之前设置len = 0

char *line = NULL;
size_t len = 0;

getline的手册页...

如果 *lineptr 设置为 NULL,并且 *n 在调用之前设置为 0,则 getline(( 将分配一个缓冲区来存储该行。 即使 getline(( 失败,用户程序也应该释放此缓冲区。

len是堆栈分配的 - 因此除非您初始化它,否则它可以包含任何值。

此外,您应该在完成之前free()line

free(line);
fclose(fp);

最后,您应该检查fopen()的返回值。

if (!fp) {
perror("fopen");
// Handle error and return if appropriate
}

getline()和窗口

我怀疑你在Windows上遇到的问题是因为Windows没有实现getline()功能。(它不是 C 标准的一部分 - 它是一个 POSIX 函数。

作为替代方案,您可以尝试使用fgets().下面是示例。

:注:请注意,在这种情况下,line的内存不是动态分配的。

char line[128] = {''};
while (fgets(line, sizeof(line), fp) != NULL) {
// etc..
}
// Do NOT call free(line) at end of scope in this case!

代码中存在多个问题:

  • line必须初始化为NULLlen初始化为0。如果不进行初始化,由于linelen具有自动存储(也称为在堆栈上(,因此您的代码具有未定义的行为,在您的情况下会导致提前终止。
  • HTML<img>通常具有诸如src=URL

你做了一些假设,这些假设不是必需的,实际上会使你的代码复杂化: * 每行仅删除第一张图片。 * 如果<img>标记和</img>位于不同的行上,则在无关的打开标记之前,可能会在同一行上出现一个关闭标记。您的第一次测试会被这种情况愚弄并产生不正确的输出。

下面是带有嵌套循环的更正版本:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
int main() {
FILE *fp;
char *line, *p, *q;
size_t len;
bool found_tag;
fp = fopen("test.html", "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %sn", "test.html");
return 1;
}
line = NULL;
len = 0;
found_tag = false;
while (getline(&line, &len, fp) != -1) {
for (p = line;;) {
if (found_tag) {
q = strstr(p, "</img>");
if (q == NULL) {
/* skip the rest of the line */
break;
}
found_tag = false;
p = q + strlen("</img>");
} else {
q = strstr(p, "<img");
if (q == NULL) {
fputs(p, stdout);
break;
}
printf("%.*s%s", (int)(q - p), p,
"The Image used to be heren");
found_tag = true;
p = q + strlen("<img");
}
}           
}
free(line);
fclose(fp);
return 0;
}

相关内容

最新更新