萌新求助

amotym 2019-05-24 01:24:06
<?xml version="1.0" encoding="utf-8"?> <test> <env mis="on" err="off" ans="off"> <info> (hold 0) (at 0 3) (sort 1 chair) (size 1 big) (at 1 1) (sort 2 plant) (size 2 big) (at 2 2) (sort 3 sofa) (size 3 big) (at 3 3) (sort 4 worktable) (size 4 big) (at 4 4) (sort 5 couch) (size 5 big) (at 5 5) (sort 6 table) (size 6 big) (at 6 6) (sort 7 teapoy) (size 7 big) (at 7 7) (sort 8 airconditioner) (size 8 big) (at 8 8) (sort 9 table) (size 9 big) (at 9 9) (sort 10 television) (size 10 big) (at 10 10) (sort 11 book) (size 11 small) (sort 12 remotecontrol) (size 12 small) (color 12 yellow) (at 12 7) (sort 13 can) (size 13 small) (color 13 green) (plate 13) (sort 14 remotecontrol) (size 14 small) (color 14 black) (sort 15 can) (color 15 blue) (size 15 small) (sort 16 remotecontrol) (size 16 small) (color 16 red) (sort 17 cup) (size 17 small) (at 17 10) (sort 18 can) (size 18 small) (color 18 white) (sort 19 book) (size 19 small) (color 19 blue) (at 19 9) </info> <mis> (at 11 7) </mis> <err> <r>(at 14 3) (at 15 1) (at 16 2) (at 18 4)</r> <w>(at 14 9) (at 15 7) (at 16 6) (at 18 6)</w> </err> <extra> </extra> </env> <instr> (:ins (:task (pickup X) (:cond (sort X remotecontrol))) (:task (pickup X) (:cond (color X black) (sort X remotecontrol))) (:task (puton X Y) (:cond (sort X can) (sort Y worktable))) (:task (puton X Y) (:cond (sort X cup) (sort Y worktable))) (:task (goto X) (:cond (sort X chair))) (:cons_notnot (:info (on X Y) (:cond (sort X remotecontrol) (color X yellow) (sort Y teapoy)))) ) </instr> <nl> Pick up a remotecontrol. Pick up the remotecontrol which is black. Put a can on the worktable. Put a cup on the worktable. Go to chair. The green can must be on the plate. The remotecontrol which is yellow must be on the teapoy. </nl> </test> C语言读取这个文件(文件名test.xml)并将info到/info中的内容以()中的内容为元素按行存入数组。并设置可以查找的指针。
...全文
120 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
拥抱Linux 2019-05-25
  • 打赏
  • 举报
回复
引用 13 楼 amotym 的回复:
[quote=引用 10 楼 拥抱Linux的回复:]既然没有报错,说明程序肯定是完全运行下去了的。
嗯,没有输出的话,看看在你的电脑上,实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢,还是没有想要的内容呢?

找到原因了,我的info前面有一个tab的位置[/quote]
哦,原来如此,程序一直没有找到一模一样的字符串"<info>"。昨天晚上尝试写代码的时候,都是顺手写下去的,对于这类读入异常的情况没有做什么识别、判断,毕竟太费事了。你如有有实际需要的话,可以自己尝试添加相关的检测代码哦。
好了,总之能得到想要的结果就好。
拥抱Linux 2019-05-25
  • 打赏
  • 举报
回复
引用 11 楼 amotym 的回复:

看样子是进入死循环了,俺估计是在 fscanf 和 fgetc 的地方进入死循环的,因为文件指针没有走到下一行。
试试把所有的 fget 替换为 fgets 函数,如下:

// 在main 函数的开头,定义一个字符数组,用来接收所读取文件的每行的末尾残余字符
char empty[100];

//fgetc(fp);
fgets(empty,10,fp);

俺这边运行下来,结果是一样的,都可以输出。你再试试。
还不行的话,可以把你实际的代码,和你实际的 xml 文件内容都放上来,俺复制过来再实际运行试试。

另外,不知道你的是纯Ubuntu还是windows下的WSL,究竟对于读取文本文件有没有影响俺不是太清楚,不过windows的换行符和linux的换行符不一样,有可能导致上面的代码下,文件指针没有前往下一行。
amotym 2019-05-25
  • 打赏
  • 举报
回复
引用 10 楼 拥抱Linux的回复:
既然没有报错,说明程序肯定是完全运行下去了的。
嗯,没有输出的话,看看在你的电脑上,实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢,还是没有想要的内容呢?
找到原因了,我的info前面有一个tab的位置
amotym 2019-05-25
  • 打赏
  • 举报
回复
引用 10 楼 拥抱Linux的回复:
既然没有报错,说明程序肯定是完全运行下去了的。
嗯,没有输出的话,看看在你的电脑上,实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢,还是没有想要的内容呢?
用的是一模一样的例子
amotym 2019-05-25
  • 打赏
  • 举报
回复
引用 9 楼 拥抱Linux 的回复:
[quote=引用 8 楼 amotym 的回复:]
谢谢啦,Ubuntu16.04中无输出

俺的系统是elementary Loki,同样是基于Ubuntu 16.04的,程序运行结果就是上面的截图那样啊。
录了一张gif动图,不知道csdn论坛支不支持,发一下试试。
[/quote]
拥抱Linux 2019-05-25
  • 打赏
  • 举报
回复
既然没有报错,说明程序肯定是完全运行下去了的。
嗯,没有输出的话,看看在你的电脑上,实际读取的test.xml文件中究竟是和上面给的例子一样有想要的内容呢,还是没有想要的内容呢?
拥抱Linux 2019-05-25
  • 打赏
  • 举报
回复
引用 8 楼 amotym 的回复:
谢谢啦,Ubuntu16.04中无输出

俺的系统是elementary Loki,同样是基于Ubuntu 16.04的,程序运行结果就是上面的截图那样啊。
录了一张gif动图,不知道csdn论坛支不支持,发一下试试。
amotym 2019-05-25
  • 打赏
  • 举报
回复
引用 7 楼 拥抱Linux的回复:
[quote=引用 6 楼 amotym 的回复:]
可不可以请教一下从info的下一行开始存储

动态申请内存吧。
在Linux环境下写了一下代码,不够优雅,仅供参考。
具体而言,是根据你提供的测试文本test.xml来写的,没有考虑其它比如文本内容有异常的情况哦。
另外,Windows环境下没有测试过,有问题的话自己调试吧,俺爱莫能助。

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

int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen("test.xml", "r");
if (NULL == fp) {
printf("Error! File open #1 failed!\n");
exit(EXIT_FAILURE);
}

/*遍历test.xml,得到所需数据的行数,即字符数组数*/
char info_start[10] = "<info>";
char info_end[10] = "</info>";
char line_check[1000];

// 按行来读取,需要额外添加一行来读取行尾换行符
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);

while (0 != strcmp(info_start, line_check) && !feof(fp)) {
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
}
int parenthesis_count = 0;
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
while (0 != strcmp(info_end, line_check)) {
char *p = line_check;
while ('\0' != *p) {
if ('(' == *p) {
while (')' != *p && '\0' != *p) {
p++;
}
if (')' == *p) {
parenthesis_count++;
} else if ('\0' == *p) {
printf("Warning : missing ')' !");
}
} else {
p++;
}
}
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
}
fclose(fp);

// 开始获取需要的字符串

fp = fopen("test.xml", "r");
if (NULL == fp) {
printf("Error! File open #2 failed!\n");
exit(EXIT_FAILURE);
}

// 指针数组,存储各个字符数组的首地址
char *whole[parenthesis_count];
int count = 0;

char search[1000];
fscanf(fp, "%[^\n]", search);
fgetc(fp);
while (0 != strcmp(info_start, search)) {
fscanf(fp, "%[^\n]", search);
fgetc(fp);
}

fscanf(fp, "%[^\n]", search);
fgetc(fp);
while (0 != strcmp(info_end, search)) {
char *p = search;
char *q = search;
while ('\0' != *p) {
p = strchr(p, '(') + 1;
q = p;
p = strchr(p, ')') + 1;
int len = p - q - 1;
char *dst = (char *)malloc(sizeof(char) * (len + 1));
for (int i = 0; i < len; i++) {
dst[i] = *q;
q++;
}
dst[len] = '\0';
whole[count++] = dst;
}
fscanf(fp, "%[^\n]", search);
fgetc(fp);
}

fclose(fp);

for (int i = 0; i < count; i++) {
printf("%s\n", whole[i]);
}

for (int i = 0; i < count; i++) {
free(whole[i]);
whole[i] = NULL;
}

return 0;
}

Linux环境,运行截图:
(1)局部,

(2)局部,

如有帮助,欢迎 及时 结帖、给分!:-)
~[/quote] 谢谢啦,Ubuntu16.04中无输出😂
拥抱Linux 2019-05-24
  • 打赏
  • 举报
回复
引用 6 楼 amotym 的回复:
可不可以请教一下从info的下一行开始存储

动态申请内存吧。
在Linux环境下写了一下代码,不够优雅,仅供参考。
具体而言,是根据你提供的测试文本test.xml来写的,没有考虑其它比如文本内容有异常的情况哦。
另外,Windows环境下没有测试过,有问题的话自己调试吧,俺爱莫能助。

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

int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen("test.xml", "r");
if (NULL == fp) {
printf("Error! File open #1 failed!\n");
exit(EXIT_FAILURE);
}

/*遍历test.xml,得到所需数据的行数,即字符数组数*/
char info_start[10] = "<info>";
char info_end[10] = "</info>";
char line_check[1000];

// 按行来读取,需要额外添加一行来读取行尾换行符
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);

while (0 != strcmp(info_start, line_check) && !feof(fp)) {
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
}
int parenthesis_count = 0;
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
while (0 != strcmp(info_end, line_check)) {
char *p = line_check;
while ('\0' != *p) {
if ('(' == *p) {
while (')' != *p && '\0' != *p) {
p++;
}
if (')' == *p) {
parenthesis_count++;
} else if ('\0' == *p) {
printf("Warning : missing ')' !");
}
} else {
p++;
}
}
fscanf(fp, "%[^\n]", line_check);
fgetc(fp);
}
fclose(fp);

// 开始获取需要的字符串

fp = fopen("test.xml", "r");
if (NULL == fp) {
printf("Error! File open #2 failed!\n");
exit(EXIT_FAILURE);
}

// 指针数组,存储各个字符数组的首地址
char *whole[parenthesis_count];
int count = 0;

char search[1000];
fscanf(fp, "%[^\n]", search);
fgetc(fp);
while (0 != strcmp(info_start, search)) {
fscanf(fp, "%[^\n]", search);
fgetc(fp);
}

fscanf(fp, "%[^\n]", search);
fgetc(fp);
while (0 != strcmp(info_end, search)) {
char *p = search;
char *q = search;
while ('\0' != *p) {
p = strchr(p, '(') + 1;
q = p;
p = strchr(p, ')') + 1;
int len = p - q - 1;
char *dst = (char *)malloc(sizeof(char) * (len + 1));
for (int i = 0; i < len; i++) {
dst[i] = *q;
q++;
}
dst[len] = '\0';
whole[count++] = dst;
}
fscanf(fp, "%[^\n]", search);
fgetc(fp);
}

fclose(fp);

for (int i = 0; i < count; i++) {
printf("%s\n", whole[i]);
}

for (int i = 0; i < count; i++) {
free(whole[i]);
whole[i] = NULL;
}

return 0;
}

Linux环境,运行截图:
(1)局部,

(2)局部,

如有帮助,欢迎 及时 结帖、给分!:-)
amotym 2019-05-24
  • 打赏
  • 举报
回复
引用 3 楼 拥抱Linux的回复:
(1)打开文件,(2)按行比较字符串,找到<info>,(3)从下一行开始读取数据,并存入字符数组,一对圆括号表示一个数组,(4)按行比较到</info>则结束读取。(5)关闭文件指针。

设置可以查找的指针。 

是什么意思?
用一个函数来传入字符指针,在前面获得的字符数组集合里查询有无相应的字符串,并且返回字符串的位置么?
可不可以请教一下从info的下一行开始存储
amotym 2019-05-24
  • 打赏
  • 举报
回复
引用 4 楼 amotym的回复:
[quote=引用 3 楼 拥抱Linux的回复:](1)打开文件,(2)按行比较字符串,找到<info>,(3)从下一行开始读取数据,并存入字符数组,一对圆括号表示一个数组,(4)按行比较到</info>则结束读取。(5)关闭文件指针。

设置可以查找的指针。 

是什么意思?
用一个函数来传入字符指针,在前面获得的字符数组集合里查询有无相应的字符串,并且返回字符串的位置么?
是的,就是这个意思。[/quote] 可不可以请教一下从info的下一行开始存储
amotym 2019-05-24
  • 打赏
  • 举报
回复
引用 3 楼 拥抱Linux的回复:
(1)打开文件,(2)按行比较字符串,找到<info>,(3)从下一行开始读取数据,并存入字符数组,一对圆括号表示一个数组,(4)按行比较到</info>则结束读取。(5)关闭文件指针。

设置可以查找的指针。 

是什么意思?
用一个函数来传入字符指针,在前面获得的字符数组集合里查询有无相应的字符串,并且返回字符串的位置么?
是的,就是这个意思。
拥抱Linux 2019-05-24
  • 打赏
  • 举报
回复
(1)打开文件,(2)按行比较字符串,找到<info>,(3)从下一行开始读取数据,并存入字符数组,一对圆括号表示一个数组,(4)按行比较到</info>则结束读取。(5)关闭文件指针。

设置可以查找的指针。 

是什么意思?
用一个函数来传入字符指针,在前面获得的字符数组集合里查询有无相应的字符串,并且返回字符串的位置么?
amotym 2019-05-24
  • 打赏
  • 举报
回复
引用 1 楼 赵4老师的回复:
仅供参考:
//NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1  14  15
//2  11  10
//3  6   4
//4  7   13
//5  9   21
//6  19  3
//7  1   5
//8  8   8
//EOF
//
// 文本文件中可能还含有其他内容,但是需要用到的内容即以上

//比如data.txt:
//NAME: essaie bla bla
//其它内容
//DIMENSION: 8
//其它内容
//DATA
//其它内容
//1  14  15
//其它内容
//2  11  10
//其它内容
//3  6   4
//其它内容
//4  7   13
//其它内容
//5  9   21
//其它内容
//6  19  3
//其它内容
//7  1   5
//其它内容
//8  8   8
//其它内容
//EOF

// 目标是要获取NAME后字串,DIMENSION后数值,以及DATA以下的数值
// 其中NAME就是随便个字句,DIMENSION是城市数量,DATA以下是城市编号,X坐标,Y坐标
// 所有的这些将赋值给一个事先定义好的结构
#include <stdio.h>
#include <string.h>
#define MAXCPL   80   //每行最大字符数
#define MAXCITY  100  //每组数据中DATA最多项数,DIMENSION的最大值
#define MAXNAMEL 32   //NAME最大长度
struct S {
    char NAME[MAXNAMEL+1];
    int  DIMENSION;
    struct D {
        int NO;
        int X;
        int Y;
    } DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
    f=fopen("data.txt","r");
    if (NULL==f) {
        printf("Can not open file data.txt!\n");
        return 1;
    }
    st=0;
    n=0;
    while (1) {
        if (NULL==fgets(ln,MAXCPL,f)) break;
        if (st==0) {
            if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;
        } else if (st==1) {
            if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
        } else if (st==2) {
            if (0==strcmp(ln,"DATA\n")) st=3;
        } else if (st==3) {
            if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
                n++;
                if (n>=MAXCITY || n>=s.DIMENSION) break;
            }
        }
    }
    fclose(f);
    printf("s.NAME=[%s]\n",s.NAME);
    printf("s.DIMENSION=%d\n",s.DIMENSION);
    for (i=0;i<n;i++) {
        printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
    }
    return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8

抱歉,还是不太明白,我们要存入的是()里的字符
赵4老师 2019-05-24
  • 打赏
  • 举报
回复
仅供参考:
//NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1  14  15
//2  11  10
//3  6   4
//4  7   13
//5  9   21
//6  19  3
//7  1   5
//8  8   8
//EOF
//
// 文本文件中可能还含有其他内容,但是需要用到的内容即以上

//比如data.txt:
//NAME: essaie bla bla
//其它内容
//DIMENSION: 8
//其它内容
//DATA
//其它内容
//1  14  15
//其它内容
//2  11  10
//其它内容
//3  6   4
//其它内容
//4  7   13
//其它内容
//5  9   21
//其它内容
//6  19  3
//其它内容
//7  1   5
//其它内容
//8  8   8
//其它内容
//EOF

// 目标是要获取NAME后字串,DIMENSION后数值,以及DATA以下的数值
// 其中NAME就是随便个字句,DIMENSION是城市数量,DATA以下是城市编号,X坐标,Y坐标
// 所有的这些将赋值给一个事先定义好的结构
#include <stdio.h>
#include <string.h>
#define MAXCPL   80   //每行最大字符数
#define MAXCITY  100  //每组数据中DATA最多项数,DIMENSION的最大值
#define MAXNAMEL 32   //NAME最大长度
struct S {
    char NAME[MAXNAMEL+1];
    int  DIMENSION;
    struct D {
        int NO;
        int X;
        int Y;
    } DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
    f=fopen("data.txt","r");
    if (NULL==f) {
        printf("Can not open file data.txt!\n");
        return 1;
    }
    st=0;
    n=0;
    while (1) {
        if (NULL==fgets(ln,MAXCPL,f)) break;
        if (st==0) {
            if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;
        } else if (st==1) {
            if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
        } else if (st==2) {
            if (0==strcmp(ln,"DATA\n")) st=3;
        } else if (st==3) {
            if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
                n++;
                if (n>=MAXCITY || n>=s.DIMENSION) break;
            }
        }
    }
    fclose(f);
    printf("s.NAME=[%s]\n",s.NAME);
    printf("s.DIMENSION=%d\n",s.DIMENSION);
    for (i=0;i<n;i++) {
        printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
    }
    return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧