Sprawdzanie czy str1 jest wyrazem wystepujacym w str2

0

Witam
Program ma za zadanie sprawdzić czy wyraz który wpisujemy w str1 wystepuje w str2. Nie mam zbytnio pomysłu żeby z str2 wrzucać do str3 az do momentu kiedy napotka spacje wiec dalem
("%c"==" ") oczywiscie jest to zle nawet kompilator zwraca błąd co do tego. Za wszelka pomoc dziekuje.

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

int main()
{
  char str1[10];
  char str2[128];
  char str3[128];
  
  int i;
  int a;
  int index=0;

  gets(str1);
  gets(str2);

  for(i=0;i<=(strlen(str2)-1);i++)
  {
    while("%c"=='');
    {
      str3[index++]==str2[i];
      a=strcmp(str1,str3);

      if(a==0)
      {
        printf("GJ");
      }
    }
  }

  return 0;
}
1

Zobacz na tą pętlę:

while("%c"==''); // Średnik!
	// Tu kończy się pętla
{ // Kod w klamrach wykona się po zakończeniu pętli
	str3[index]++ = str2[i];
	...
}

Zamiast robić taki warunek w for:

i <= (strlen(str2) - 1)

Czytelniejsze jest:

i < strlen(str2)
0

Nie jest przypadkiem tak ? Ale ogólnie ten warunek z tym "%c" jest prawidłowy ?
przy tej linijce kodu daje mi : error empty character const

 for(i=0;i<=(strlen(str2)-1);i++)
            {
                while("%c"=='')
 zaczyna sie -> {
                str3[index++]==str2[i];
                a=strcmp(str1,str3);

                        if(a==0)
                    {
                        printf("GJ");
                    }

konczy sie-> }

                }
2

while("%c"==''); - co ten warunek Twoim zdaniem robi?


Plus, na marginesie, chcąc wykorzystywać strlen w pętli, nie pisz tak:

for (i = 0; i < strlen(str); ++i) {
  /* ... */
}

tylko tak:

unsigned int len = strlen(str);

for(i = 0; i < len; ++i) {
  /* ... */
}

Chodzi o względy wydajnościowe - warunek w pętli musi być obliczony za każdym obrotem pętli, a strlen ma z kolei złożoność O(n) (strlen musi za każdym razem dojść do końca ciągu znaków, aby znać jego długośc), zatem z prostej pętli O(n) robisz u siebie zupełnie niepotrzebnie O(n^2).

0

Poprawione ale nadal mam ten problem że nie wyświetla mi błąd w while. Rozumiem względy wydajnościowe ale na razie mi w ogole nie dziala.

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

int main()
{
    char str1[10];
    char str2[128];
    char str3[128];
    int i;
    int a;
    int b;
    int index=0;

    gets(str1);
    gets(str2);
    b=strlen(str2);

            for(i=0;i<b;i++)
            {
                while("%c"=='')   // error: empty character const 
                {
                str3[index++]==str2[i];
                a=strcmp(str1,str3);

                        if(a==0)
                    {
                        printf("GJ");
                    }

                }

                }



    return 0;
}
1

Ciąg znaków %c na pewno nie równa się spacji, więc ten warunek nigdy nie będzie prawdziwy.

Empty character const masz dlatego że pomiędzy apostrofami nie ma spacji.

0

Okej juz poprawione, rzeczywiście był w tym problem. Po kompilacji na wyraz ania i drugi łańcuch ania ma kota program nic mi nie zwraca.

0

Co dokładnie ma ten program robić? Raz piszesz

Program ma za zadanie sprawdzić czy wyraz który wpisujemy w str1 wystepuje w str2.

a potem

Nie mam zbytnio pomysłu żeby z str2 wrzucać do str3 az do momentu kiedy napotka spacje wiec dalem

Ma być tak że dopóki znaki w str1 są takie same jak w str2 to są kopiowane do str3 czy jak?

0

Kod który napisałem dla mnie działa tak ze dopóki nie napotka spacji w str2 to wszystkie znaki przekazuje do str3 i porównuje z str1. ( przynajmniej tak mi się wydaję )
Zadanie brzmi : Sprawdź czy wyraz z str1 występuje w zdaniu str2.

3
if(strstr(sentence, fragment) != NULL) {
    /* ... */
}
0

Dziękuję bardzo wszystko działa.

0

Ale wciąż nie rozumiesz co jest nie tak z while("%c" == ' ')?

0

jesli mam byc szczery to nadal nw dlaczego ten poprzedni kod nie działa tak jak powinien ale po rozwiazaniu nie sadzilem ze ktos ma na tyle cierpliwosci zeby tlumaczyc.

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

int main()
{
	char str1[10];
	char str2[128];
	char str3[128];

	int i;
	int a;
	int index = 0;

	/* Dwie poniższe funkcje pobierają ciąg znaków i wrzucają do bufora.
	   Ale problem z nimi jest taki że nie sprawdzają ile znaków może się tam zmieścić
	   W rezultacie może to przepełnić bufor, a funkcja będzie napisywała obszar pamięci
	   którego nie pownna ruszać. 
	*/
	gets(str1);
	gets(str2);
	int b = strlen(str2);

	/* Ta pętla będzie leciała litera po literze w podanym przez użytkownika wyrazie */
	for (i = 0; i < b; i++)
	{
		/* %c używa się jako format dla printf/scanf, ale tak na prawdę jest to tylko ciąg znaków.
		   To porównanie jest złe bo chcesz porównać 2 znaki (% oraz c) ze spacją co jest...  niemożliwe
		   
		   W sumie nie wiem co robi tutaj while bo jeżeli chodzi o przerwanie pętli to wystarczyło by
		   if (str[i] == ' ')
				break; // Break wychodzi z pętli
			
			Gdyby poprawić warunek w while to program utknąłby w niekończącej się pętli.
		*/
		while ("%c" == ' ') 
			; /* Postawiłeś średnik za while co oznacza że jest to pusta pętla (nie ma ciała) */
		{
			/* Używając == porównujesz, nie przypisujesz */
			str3[index++] == str2[i];

			a = strcmp(str1, str3);

			if (a == 0) /* Jeżeli ciągi znaków mają taką samą zawartość */
			{
				printf("GJ");
			}
		}
	}

	return 0;
}

Od dawna można już deklarować zmienne w środku funkcji, co poza czytelnością ma taką zaletę że ograniczamy widoczność zmiennej.
Czyli zamiast:

int i;
for (i = 0; i < max; i++)
{
	// Tu i jest dostępne
}
// Tu również

Pisze się

for (int i = 0; i < max; i++)
{
	// i jest widoczne tylko tu
}
// Tutaj coś takiego jak i nie istnieje.
0

if (str[i] == 'c')
break; // Break wychodzi z pętli

Przeciez mi chodzilo zeby porownac caly lancuch, tutaj chyba doszedł by do spacji po pierwszym wyrazie i wyszedłby zostawiając całą resztę ? Proszę mnie poprawić jeśli się mylę.

0

Napisałeś

z str2 wrzucać do str3 az do momentu kiedy napotka spacje

Więc taki kod:

if (str2[i] == ' ') // Tu miała byś spacja a nie 'c', ups...
	break;

by to robił.

0

Miałem na myśli:
Ania ma kota.
Więc pętla czyta pierwszy wyraz Ania porównuje z wyrazem który był podawany w str1 jeśli jest 0 to leci dalej do konca łańcucha str2 takie miałem zamiary wiem ze jesli chodzi o umiejętności sporo mi brakuje.

0

Gdzieś czytałem ze wlasnie to niby tak ma działać niestety ostatecznie tak nie wyszło.

0

To byłoby bez sensu.
0 oznacza że łańcuch A równa się łańcuchowi B - co oznaczałoby że słowo str1 występuje w str2, wtedy należałoby wyświetlić komunikat i wyjść z pętli - po co dalej sprawdzać?

0

a gdyby to nie był pierwszy wyraz a 10 to dalej by sprawdzało w sensie że pierwszy wyraz itd ? i każdy wyraz z osobna by porównywało?

1

Tobie chodzi o taki kod:

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

int main()
{
	char input[10];
	char sentence[100];
	char word[10];

	fgets(input, 10, stdin); // fgets jest bezpieczniejszy - sprawdza rozmiar bufora
	input[strcspn(input, "\n")] = 0; // Usuwanie znaków nowej linii

	fgets(sentence, 100, stdin);
	sentence[strcspn(sentence, "\n")] = 0;

	int word_index = 0;
	int length = strlen(sentence);

    for(int i = 0; i < length; i++)
	{
		// Sprawdzanie czy spacja albo ostatni znak (length - 1)
		if (sentence[i] == ' ' || i == length - 1)
		{
			/* Dzięki temu że ustawimy 0 na tej pozycji, strcmp nie będzie porównywał pozostałych znaków
			   w tym buforze, co potrzebujemy aby nie czytać pozostałości z poprzednich słow.
			   Możesz usunąć tą linię i zobaczyć o co mi chodzi.
			*/
			word[word_index] = 0;
			printf("Sprawdzam: \"%s\" z \"%s\"\n", input, word);
			if (strcmp(input, word) == 0) // Jeżeli słowa są takie same
			{
				printf("Znaleziono!\n");
				break; // Wyjdź z pętli
			}
			/* Gdy wyrazy nie są takie same ta linia wykona się ustawiając word_index na 0
			   dzięki temu będziemy od nowa zapełniać bufor 
			*/
			word_index = 0;
		}
		else
		{
			word[word_index++] = sentence[i]; // Przepisywanie znaków
		}
	}
}

Choć nie jest w 100% bezpieczny bo możesz wyjechać poza tablicę word, ale implementację takiego zabezpieczenia zostawiam już Tobie ;)

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