这对我来说已经很久了......
好的,这就是我的目标:读入XML文本文件,将每个单词和标签分成数组中的自己的行。
例如,如果我将此文本输入我的程序:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
我会得到这个:
<note>
<to>
Tove
</to>
<from>
...
现在我的代码可以成功地执行此操作,但只能使用以下单词而不是上面的列表:
note
to
Tove
...
我想保留标签,否则我无法用它做我想做的事。所以我一直试图让它也添加标签,但一直都失败了
好的,这是我的代码:
//While the file is not empty
while(fgets(buffer, sizeof(buffer), stdin) != NULL){
int first = 0;
int last = 0;
//While words are left in line
while(last < INITIAL_SIZE && buffer[last] != '\0'){
int bool = 0;
//Tag detected
if(buffer[last] == '<'){
while(buffer[last] != '>'){
last++;
}
bool = 1;
}else{
//While more chars are in the word
while(last < INITIAL_SIZE && isalpha(buffer[last])){
last++;
}
}
//Word detected
if(first < last){
//Words array is full, add more space
if(numOfWords == sizeOfWords){
sizeOfWords = sizeOfWords + 10;
words = (char **) realloc(words, sizeOfWords*sizeof(char *));
}
//Allocate memory for array
words[numOfWords] = (char *) calloc(last-first+1, sizeof(char));
for(i = 0; i < (last-first); i++){
words[numOfWords][i] = buffer[first + i];
}
//Add terminator to "new word"
words[numOfWords][i] = '\0';
numOfWords++;
}
//Move "Array Pointers" accordingly
last++;
first = last;
}
}
任何人都有任何想法,上面的代码是打印输出:
<note
<to
Tove
to
<from
Jani
from
<heading
...
Don
t
forget
me
this
weekend
</body
</note
所以在这篇文章之后,有没有人知道我如何修改我当前的代码才能使其工作?或者其他人有其他选择吗?任何建议或帮助表示赞赏。
答案 0 :(得分:0)
我的基本思维方式是:
first
是当前单词中包含的第一个字母;
last
是当前单词中第一个未包含的字母。
在您的程序中,当您检测到代码时,您不会包含>
。此外,最后不需要last++
,因为正在解析单词,一旦包含>
,它就没用了。此外,您忘记不仅要检查\0
作为字符串的结尾,还要检查\n
作为行尾。
这是我的解决方案:
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
int first = 0;
int last = 0;
//While words are left in line
while (last < INITIAL_SIZE && buffer[last] != '\0'
&& buffer[last] != '\n') { // <--------- Add this
int Bool = 0;
//Tag detected
if (buffer[last] == '<') {
while (buffer[last] != '>') {
last++;
}
last++; // <--------- This
Bool = 1;
} else {
//While more chars are in the word
while (last < INITIAL_SIZE && isalpha(buffer[last])) {
last++;
}
}
//Word detected
if (first < last) {
//Words array is full, add more space
if (numOfWords == sizeOfWords) {
sizeOfWords = sizeOfWords + 10;
words = (char **) realloc(words,
sizeOfWords * sizeof(char *));
}
//Allocate memory for array
words[numOfWords] = (char *) calloc(last - first + 1,
sizeof(char));
for (i = 0; i < (last - first); i++) {
words[numOfWords][i] = buffer[first + i];
}
//Add terminator to "new word"
words[numOfWords][i] = '\0';
numOfWords++;
}
//Move "Array Pointers" accordingly
first = last; // <--------- And change this
}
}
答案 1 :(得分:0)
尽管任何人都会使用它是非常值得怀疑的,但我使用布尔类型逻辑让它工作。
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
int first = 0;
int last = 0;
//While words are left in line
while (last < INITIAL_SIZE && buffer[last] != '\0' && buffer[last] != '\n'){
int Bool = 0;
//Tag detected
if (buffer[last] == '<'){
while (buffer[last] != '>')
last++;
Bool = 1;
}else
//While more chars are in the word
while(last < INITIAL_SIZE && !isspace(buffer[last]) && buffer[last] != '<')
last++;
//Word detected
if (first < last) {
//Words array is full, add more space
if (numOfWords == sizeOfWords) {
sizeOfWords = sizeOfWords + 10;
words = (char **) realloc(words, sizeOfWords * sizeof(char *));
}
//Allocate memory for array
words[numOfWords] = (char *) calloc(last - first + 1, sizeof(char));
int xHolder = 0;
if(buffer[first] == '/'){
words[numOfWords][0] = '<';
xHolder++;
Bool++;
}
for (i = 0; i < (last - first + Bool); i++) {
words[numOfWords][xHolder] = buffer[first + i];
xHolder++;
}
//Add terminator to "new word"
words[numOfWords][i] = '\0';
numOfWords++;
}
//Move "Array Pointers" accordingly
last++;
first = last;
}
}
答案 2 :(得分:0)
我在这里给出的最好的建议是当我在comp.lang.c上发布this时给我的。
<强>功能强>
几乎无处不在,你写了一个全行注释,注释中的重要单词应该是当时调用的函数的名称。
ProcessFile
while(fgets..)
ProcessWords()
ProcessWords
if(DetectTag)
...
以这种方式重构使得复杂的代码更容易阅读(对你而言)。它允许您的顶级逻辑读取像伪代码一样,而所有的虚拟位都可以组合在一起。也许有一天,标签将使用花括号。将您的文字放在#define
s甚至enums
中。这样,以后可以轻松地进行简单的语法更改。
目标是你能够同时在屏幕上看到整个功能体。这允许您分别验证每个部分。
答案 3 :(得分:-1)
你的内循环可能有问题