Как анализировать данные между тегами из текстового файла в C

Я хочу напечатать данные между тегами из текстового файла, используя C.

Вступительное заявление: (ПЕРСОН) Марк Цукерберг (/ PERSON) является предпринимателем из (РАСПОЛОЖЕНИЕ) США (/ МЕСТО). Он также является генеральным директором (ORGANIZATION) Facebook (/ ОРГАНИЗАЦИЯ).

Вывод: Марк Цукерберг США Facebook.

Мой программный код:

const char* getfield(char* line, int num) { const char* tok; for (tok = strtok(line, "/>"); tok && *tok; tok = strtok(NULL, "<\n")) { if (!--num) return tok; } return NULL; } int main() { char line[500000]; while (fgets(line, 500000, stdin)) { char* tmp = strdup(line); printf(" %s\n", getfield(tmp, 2)); free(tmp); } } 

Это только печать Марка Цукерберга. Другие данные между тегами не отображаются? Может кто-то, пожалуйста, помогите, где я ошибся? Я только начал изучать обработку файлов на C, поэтому руководство высоко ценится. Благодарю.

EDIT: Пожалуйста, замените “(” на “”.

getfield ваш getfield не делает то, что вы хотите. На примерной строке (перемещение скобок) ваш цикл for запустит strtok , вырезается при первом «>» ( strtok использует любой из символов в качестве разделителя), так что после 1-го «ЧЕЛОВЕКА». После этого вы вырезаете только «> \ n», поэтому в конце этого тега. При достаточно большом количестве, которое оно дало бы (внутри цикла):

  is a entrepreneur from LOCATION> USA /LOCATION>. He is also the CEO of ORGANIZATION> Facebook /ORGANIZATION> 

Вы должны чередовать поиск: искать закрывающий тег (>), затем искать открывающий тег (<): in beetween - это содержимое 1-го тега. Затем пропустите закрывающий тег и начните снова то же самое до конца. Что-то вроде:

 char *gf(char *line, int num) { char *n1, *n2; // comments are for the 1st loop // search end of 1st tag (opening) n1 = strtok(line, ">\n"); while(n1) { // search begin of 2nd tag (correp. closing) n2 = strtok(NULL, "<"); // this one is good, shall we return it? if (num == 0) { return(n2); } printf("Found: %s\n", n2); // search end 2nd tag (have to skip it) n1 = strtok(NULL, ">\n"); // search end of 3rd tag (opening), then loop (same situation) n1 = strtok(NULL, ">\n"); } return NULL; } 

Обратите внимание, что этот код не очень приятный. Если у вас есть «>» или «<» внутри обычного текста, это пойдет не так (как у вас собственный код, BTW). И это не останавливается должным образом, если строка не заканчивается символом \ n.

Примечание: если вам нужен надежный подход, вам придется читать tags. Я имею в виду найти тег (материал beetween “<" и ">“), затем найти соответствующий закрывающий тег (тот же, но с / и тем же контентом), а затем только получить текст внутри или сгенерировать ошибку.

EDIT: я изменил функцию так, чтобы она возвращала элемент num . Теперь вам придется иметь дело с функцией main() способной вызвать эту функцию несколько раз, с увеличением значений num , сохранения (или печати) результата до получения ответа NULL. В качестве домашней работы вам нужно будет найти, как управлять главной строкой (строкой) в main чтобы можно было выполнить последовательные вызовы (иначе вы действительно получите только первый тег) 🙂

Ваш вызов fgets() читает всю строку. Затем вы вызываете getfield() и печатаете результат. Затем вы отбрасываете остальную часть прочитанного, пытаетесь прочитать больше, больше нет, и вы выходите из цикла. Вам нужно продолжать цикл, пока вы не обрабатываете необработанные данные.

Изменить: Вот пример кода, который поможет вам начать:

 int main() { char line[500000]; while (fgets(line, 500000, stdin)) { char *arg = line; const char *tok; while ((tok = getfield(arg, 2)) != NULL) { printf("%s\n", tok); arg = NULL; } } } 

Но обратите внимание, что это не настоящее решение. Во-первых, это даст вам текст за пределами тегов, а также текст внутри тегов, поэтому вам нужно будет пропустить это. Для другого, он не будет работать нормально, если ваш входной файл содержит более одной строки.

EDIT: Изменено ( и ) это для < и > соответствий в коде и в объяснении. Спасибо, Том.

Вот решение. Попытайтесь понять код. Кроме того, не стесняйтесь изменять его в соответствии с вашими потребностями. В основном, вам нужно выполнить поиск тегов <> или / и путем сканирования символов < и > . Когда вы сталкиваетесь с символом < приращиваете свой индекс до тех пор, пока не встретите символ > Когда вы столкнетесь с символом > начните копирование символа, следующего за символом > пока вы не встретите другой символ < а затем повторите этот процесс, пока не достигнете нулевого завершающего символа '\0' .

 #include //#pragma warning(disable : 4996) void removeTags(char inpData[], int dataLen); int main() { char letter, fileData[400]; int numLetters; FILE *pfile; pfile = fopen("test.txt", "r"); if (pfile == NULL) { printf("Error!Can not open file"); } else { numLetters = 0; while ((letter = fgetc(pfile)) != EOF) { fileData[numLetters] = letter; numLetters++; } fileData[numLetters] = '\0'; printf("File Data:\n\n"); printf("%s", fileData); printf("\nRemoving Tags.....\n"); removeTags(fileData,numLetters); } return 0; } void removeTags(char inpData[],int inpLen) { char character,temp[400]; int index = 0,tindex=0; while (inpData[index] != '\0') { if ((inpData[index] >= 'A' && inpData[index] <= 'Z') || (inpData[index] >= 'a' && inpData[index] <= 'z') || inpData[index] == ' ' || inpData[index] == '.') { temp[tindex] = inpData[index]; index++; tindex++; } else if (inpData[index] == '<') { while (inpData[index] != '>') { index++; } index++; temp[tindex] = ' '; if (tindex > 0) { tindex++; } } else { break; } } temp[tindex] = '\0'; printf("%s", temp); }