C, zamiana tagów HTML na duże litery

0

Nie spotkalem sie nigdzie z watkiem jak to napisac w czystym C. Odpowiedz jest dobra, po prostu mam zbyt dlugi czas wykonania. Głowię się nad takim zadaniem ze SPOJ:

Tresc: Często się zdarza, że pisząc stronę internetową piszemy tagi HTMLowe w postaci dużych, a czasami małych liter. Powoduje, że kod strony wygląda nieestetycznie. Twoim zadanie jest napisanie programu, który przerobi wszystkie tagi HTMLowe na duże litery, tzn, wszystkie litery pomiędzy znakami "<" a ">" zamieni na duże litery.

Input - Na wejściu znajduje się fragment kodu HTMLowego.
Output - Na wyjściu znajduje się kod HTML z wejścia, tyle tylko, że wszystkie tagi HTMLowe składają się z dużych liter.

Input:
<html>
<head>
<TITLE>To jest tytul</Title>
</head>
<body>
<b>Cos tam</b>
</body>
</html>


Output:


<HTML>
<HEAD>
<TITLE>To jest tytul</TITLE>
</HEAD>
<BODY>
<B>Cos tam</B>
</BODY>
</HTML> 

Moj kod:

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


int main()
{
    int i, MAX = 60;
    char line[MAX];
    char sign = 'a';    //'a' - wlaczony tryb poprawy liter, 'b' - wylaczony


    fgets(line,MAX,stdin);     // wczytywanie linii z stdin


    while(line[0] != '\n')      // Dopoki nie bedzie pustej linii
    {
        i = 0;


        while(i < strlen(line)) 
        {
            if (line[i]=='<')
            {
                sign = 'b';
                ++i;
            }
            else if(line[i]=='>')
            {
                sign = 'a';
                ++i;
            }
            else if(sign=='b' && line[i]>='a' && line[i]<='z')
            {
                line[i] -= 32;
                ++i;
            }
            else
            {
                ++i;
            }


        }


        line[ strlen(line) - 1  ] = '\0';
        printf("%s\n", line);
        fgets(line,MAX,stdin);
    }


    return 0;
} 
0

nie mozesz szukac znakow < albo > bo co jesli w tekscie takie wystepuja? To Twoj parser tego nie ogarnie

Musisz szukac CALYCH wyrazow (tagow) bo inaczej to nie bedzie dzialac.

I tak bedzie mial wady ale...

skorzystaj z funkcji toupper()

0

możesz wyrzucić operację:

 line[ strlen(line) - 1  ] = '\0';

pamiętając, że

  printf("%s\n", line);

trzeba zmienić na

  printf("%s", line);

Zresztą, tak jak masz, to przy linii dłuższej niz 60 znaków będziesz miał zjedzony jeden znak. Obawiam się, że ten algorytm nie działa dobrze

0

Dodałem funkcję toupper i posłuchałem rady kaczusa.
Czyli mam szukać wyraz po wyrazie czy jest on równy jakiemukolwiek tagowi HTML?

0

warunek line[i]>='a' && line[i]<='z' jest niepotrzebny, wystarczy wykluczenie slasha.
Zapisywanie początku tagu w char to dosyć dziwny pomysł, nie szkodzi specjalnie, ale dlaczego po prostu nie użyjesz boola?
Sądze że będzie to nieco czytelniejsze.

0

Nie uzywalem boola, bo w C nie ma takiego typu. Masz racje, przy uzyciu funkcji toupper() jest on juz niepotrzebny.
Po poprawkach nadal przekraczam dozwolony czas.
Kod po poprawkach:

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


int main()
{
    int i, MAX = 60;
    char line[MAX];
    char sign = 'a';    //'a' - wlaczony tryb poprawy liter, 'b' - wylaczony

    fgets(line,MAX,stdin);

    while(line[0] != '\n')      // Dopoki nie bedzie pustej linii
    {
        i = 0;

        while(i < strlen(line)) 
        {
            if (sign == 'a') 
            {
                if (line[i]=='<')
                {
                    sign = 'b';
                    ++i;
                }
                else
                {
                    ++i;
                }
            }
            else if(sign=='b')
            {
                if(line[i]=='>')
                    sign = 'a';
                else 
                    line[i] = toupper(line[i]);
                ++i;
            }
        }

        printf("%s", line);
        fgets(line,MAX,stdin);
    }

    return 0;
}
 
0
  • Możesz zmniejszyć ilość if'ów o jeden poziom.
    int i;
    const int MAX = 160;
    char line[MAX];
    char sign = 'a';

     while(scanf("%s",&line[0]) != EOF)
    {
        for(i=0; i < strlen(line); i++)
        {
            if (line[i]=='<')
            {
                sign = 'b';
            }
            else if(line[i]=='>')
            {
                sign = 'a';
            }
            
            if(sign=='b')
            {
                line[i] = toupper(line[i]);
            }
        }
        
        printf("%s\n", line);
 
    }

Takie coś tam działa i przechodzi.

PS. sign mógłby być int'em albo bool'em jak wspomniano wyżej.

0

Teraz mam cos takiego:

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

int main()
{
    int i;
    const int MAX = 160;
    char line[MAX];
    bool on = 0;
 
    while(fgets(line,MAX,stdin) != NULL)
    {
        for(i=0; i < strlen(line); i++)
        {
            if (line[i]=='<')
            {
                on = 1;
            }
            else if(line[i]=='>')
            {
                on = 0;
            }
 
            if(on==1)
            {
                line[i] = toupper(line[i]);
            }
        }
 
        printf("%s\n", line);
    }

    return 0;
}
 

I po wpisaniu pustej linii (sam Enter) nie konczy pracy programu.

0

Ok, wszystko dziala, czas w porzadku, dzieki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1