Найти теги в файле с помощью указателей - PullRequest
1 голос
/ 15 февраля 2020

Так что я совсем новичок в использовании указателей, и, возможно, то, что я пытаюсь сделать, даже не имеет смысла ...? Я работаю над проектом, который просит меня найти теги html в файле путем поиска начальной и конечной точек тегов (считываемых из файла).

В настоящее время у меня есть весь файл, записанный в одномерный массив символов, и я должен выполнить поиск в массиве, чтобы найти любой тег, начинающийся и заканчивающийся идентификаторами '<' и '>', строго используя указатели. Если между идентификаторами есть «/» или пробел, то это не тег, и нам не нужно хранить ссылку на него. Массив настроен таким образом, что он сохраняет форматирование исходного файла.

Как только тег найден, мы должны найти в массиве совпадения и посчитать, сколько там одинаковых тегов. Мне запрещено хранить найденные теги в массиве, но я могу хранить указатель на начало и конец каждого тега в массиве указателей. Любое руководство будет оценено. Это код, который у меня есть, возможно, он работает, но я хочу немного попрактиковаться с указателями ...

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

int main(int argc, char **argv)
{
    FILE *fptr;
    char maxLength[10] = "";// this is where each tag less than 10 characters long will be held
    char htags[100][10]; // Array that will be used to store each tag found
    int tagCounts[100]; // Array that will count the amount of times a tag shows up
    for (int i = 0; i < 100; i++)
        tagCounts[i] = 0;
    int n = 0;
    char *filename = argv[1]; // Input file to be read
    fptr = fopen(filename, "r"); // Read through the file
    if (fptr == NULL)
    {
        printf("File not found...");
        return 0;
    }
int c;
    if (fptr != NULL)
    {
        while (c = fgetc(fptr) != NULL)// making sure we are reading until the very end of the file
        {
            char c = fgetc(fptr); // reading character by character

            if (c == '<' && !feof(fptr))// searching for tags that start with '<'
            {
                char ch = fgetc(fptr);
                if (ch != '/') // checking to see if it is actually a tag
                {
                    int i = 0;
                    strcpy(maxLength, ""); // this is what we will use to store the tags when we find one
                    while (ch != 10 && ch != '>' && ch != ' ')
                    {
                        maxLength[i] = ch; // adds the next character to str[] until
                        // it gets to the end of the tag
                        ch = fgetc(fptr);
                        i++; // increment i so that the characters don't overlap in the array
                    }

                    maxLength[i] = '\0'; // Used to indicate the termination of the character string for a tag

                    int number = 1;

                    for (int i = 0; i < n; i++)// Checking to see if the tag has already
                                               // been found before in the file
                    {
                        if (strcmp(htags[i], maxLength) == 0) // tag has been found before
                        {
                            tagCounts[i]++; // increase the count by 1
                            number = 0;
                            break;
                        }
                    }

                    if (number == 1)
                    {
                        strcpy(htags[n], maxLength); // store the newly found tag in the array
                        tagCounts[n]++;
                        n++; // A new tag has been found, so we must create another element in the array and subsequently increase it's count
                    }
                }
            }
        }
    }
    for (int i = 0; i < n; i++)
    {
        printf("Tag-> %s -> Appeared %d time(s)\n", htags[i], tagCounts[i]);
    }
}

Выше приведено описание того, что должна делать программа (возьмите текстовый файл и сосчитайте теги ), но теперь я должен строго использовать указатели для ссылки на элементы в массиве, получить строку между ними, а затем сосчитать аналогичные ...

Массивы, которые я инициализировал для приведенной ниже программы:

char buffer[100000]; 
char *sTags[100], *eTags[100];

Это то, что я смог придумать, но я только что ударил стену в моем понимании материала.

    char *contents = buffer;    

    if(buffer != NULL){
       char *c = contents;

        if(*c == '<'){
            char *ch = contents;

            if(*ch != '/'){
                while(*ch != '\0' && *ch != '>' && *ch != ' '){
                    contents++; //nothing is telling us it isn't a tag, so find the end
                    //found the tag, so get the location right before it?
                    if(*ch == '>'){
                        *sTags = contents--;
                    }
                    *sTags = '\0';
                }
                //This is where I am confused.
                //How would I go about comparing the string to other strings
                //throughout the file if it is not stored somewhere..?
            }
        }
    }
    printf("%s", sTags);

1 Ответ

1 голос
/ 15 февраля 2020

Две вещи для рассмотрения.

1) isspace (c)

Возможно, вы захотите использовать isspace (c) вместо c == ''. https://www.techonthenet.com/c_language/standard_library_functions/ctype_h/isspace.php

Так как проверка (c == '') позволяет тегам пересекать концы строк. Например, что бы ваш код делал с таким четырехстрочным файлом, как этот?

<alpha>
<be
ta>
<gamma>

Будет ли он находить теги поиска типа "", " ", и" "? Хм ... Это то, что вы проверяете (c == 10) для?

2) strncmp ()

Не знаю Полностью понять требование только для указателей не хранить копии тегов. Но strncmp () может помочь. https://www.tutorialspoint.com/c_standard_library/c_function_strncmp.htm Если у вас есть начальный и конечный указатели тега, тогда длина равна (end-beg) +1).

Итак, в вашем первом методе longi sh main () вы перебираете известные теги, если они есть, для проверки на совпадения.

Ваш указатель на основе Вы можете l oop над вашими известными тегами, и вам нужно вызывать strncmp (), только если тег-кандидат имеет ту же длину, что и известный тег.

Наконец

Наконец, бонусные баллы за Отладка printf (), я нахожу это супер полезным в моем коде. Не стесняйтесь распечатывать вещи.

И если у вас еще нет небольшого тестового файла для отладки, я бы посоветовал вам сделать один.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...