C 删除<;img></img>;标签
我有这个密码。代码的目的是打印C 删除<;img></img>;标签,c,string,getline,C,String,Getline,我有这个密码。代码的目的是打印之前的所有内容和之后的所有内容。不应打印和之间的所有内容。然而,我有两个问题 代码是在windows(gcc编译器)上编译的,但当我运行它时,它只是说“程序停止工作了” 代码正在打印所有内容。它甚至正在打印, 以及介于两者之间的所有内容 我的#包括: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #incl
之前的所有内容和
之后的所有内容。不应打印
和
之间的所有内容。然而,我有两个问题
,
以及介于两者之间的所有内容#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#包括
#包括
#包括
#包括
#包括
代码:
void replacer_和_打印(文件*fp){
字符*行;
尺寸透镜;
阅读;
bool found_tag=false;
内线仓库;
字符*在标签前;
标签后面的字符*;
while((read=getline(&line,&len,fp))!=-1){
如果(
(_tag=strstrstr(第,“”)行之前)!=NULL)&&
(_tag=strstrstr(第行,“”)之后)!=NULL)
) {
行\u storer=前\u标记-行;
printf(“%s”,第行,第行);
printf(“用于此处的图像\n”);
行\u storer=在\u标记后-行+strlen(“”);
printf(“%s”,行+行存储器);
}如果((在标签=strstrstr(行,“”)之前)!=NULL,则为else{
行\u storer=前\u标记-行;
printf(“%s”,第行,第行);
found_tag=true;
}如果((在标签=strstr(行,“”)之后)!=NULL){
发现标签=假;
行\u storer=在\u标记后-行+strlen(“”);
printf(“%s”,行+行存储器);
}如果(!found_tag){
printf(“%s”,第行);
}
}
fclose(fp);
}
test.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>
这是一个测试页面
这里有更多的文字供更多测试!!!!
www.website.com/image.png
更多的话
测试123
输出:
<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>
这是一个测试页面
这里有更多的文字供更多测试!!!!
这张照片曾经在这里
更多的话
测试123
假设:
There will only be one <img>
There will only be one </img>. The </img> tag will always be after the <img>
将只有一个
只有一个。标签将始终位于
在第一次调用getline()
之前,需要设置len=0
从getline
的手册页
如果在调用之前*lineptr设置为NULL且*n设置为0,则getline()将分配一个缓冲区来存储该行。即使getline()失败,用户程序也应释放此缓冲区
len
是堆栈分配的-因此除非初始化它,否则它可以包含任何值
此外,在完成之前,您应该是free()
ingline
free(line);
fclose(fp);
最后,您应该检查fopen()
中的返回值
getline()
和Windows
我怀疑您在Windows上遇到的问题是因为Windows没有实现getline()
函数。(它不是C标准的一部分-它是一个POSIX函数。)
您也可以尝试使用fgets()
。下面的例子
N.B.注意,在这种情况下,行
的内存不是动态分配的
char line[128] = {'\0'};
while (fgets(line, sizeof(line), fp) != NULL) {
// etc..
}
// Do NOT call free(line) at end of scope in this case!
您的代码中存在多个问题:
必须初始化为行
和NULL
为len
。在没有初始化的情况下,由于0
和line
具有自动存储(也称为堆栈上),因此代码具有未定义的行为,在您的情况下会导致提前终止len
- HTML
标记和
位于不同的行上,则可能会有一个关闭标记出现在不相关的打开标记之前的同一行上。您的第一个测试将被这种情况所愚弄,并产生不正确的输出
以下是带有嵌套循环的更正版本:
#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 %s\n", "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 here\n");
found_tag = true;
p = q + strlen("<img");
}
}
}
free(line);
fclose(fp);
return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(){
文件*fp;
字符*行,*p,*q;
尺寸透镜;
布尔找到了标签;
fp=fopen(“test.html”,“r”);
如果(fp==NULL){
fprintf(stderr,“无法打开%s\n”,“test.html”);
返回1;
}
行=空;
len=0;
发现标签=假;
while(getline(&line,&len,fp)!=-1){
对于(p=line;;){
如果(找到标签){
q=strstr(p,“”);
if(q==NULL){
/*跳过剩下的部分*/
打破
}
发现标签=假;
p=q+strlen(“”);
}否则{
q=strstr(p),“欢迎来到StackOverflow!在大多数情况下,这是一篇很好的第一篇文章;但是,你应该在文章中包含任何你不会帮助解决的错误。你声明代码不会在Windows上编译,你能包含编译器错误吗?”“@c1moore一点也没有错误。它编译得很好。但是,当我运行它时,它只是停止工作,那么为什么你在帖子中包含了#1?”很抱歉,@c1moore的措辞是错误的。编辑了帖子提示:当输出有问题时,用哨兵包围字符串输出,如
,并在每个输出结束时使用\n
。它最好暴露过多的白色。”-空格、换行、回车问题。例如printf(“%s”,行存储器,行);
-->printf(“\n”,行存储器,行)
添加了这两个内容,仍然没有打印任何内容,但现在它至少没有崩溃。由于某种原因,它不符合while循环条件。因此它不会进入while循环。@SarahChan:在你的问题中,你说“代码正在打印所有内容”“。现在你说的正好相反。你能澄清一下吗?@SarahChan:我没有访问mingw
或Windows计算机的权限。但是,你确定文件被正确打开了吗?我问你,因为你没有检查fopen()的返回值。”
@SarahChan:如果您还没有这样做,我认为现在是使用调试器的好时机(我认为mingw
提供了gdb
)。
if (!fp) {
perror("fopen");
// Handle error and return if appropriate
}
char line[128] = {'\0'};
while (fgets(line, sizeof(line), fp) != NULL) {
// etc..
}
// Do NOT call free(line) at end of scope in this case!
#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 %s\n", "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 here\n");
found_tag = true;
p = q + strlen("<img");
}
}
}
free(line);
fclose(fp);
return 0;
}