funkcja zwracająca wskaźnik do drugiego wystąpienia danego znaku w łańcuchu

0

Witam,
napisałem funkcję, która ma za zadanie zwrócenie wskaźnika do drugiego wystąpienia danego znaku w łańcuchu znaków. Wydaje mi się, że działa prawidłowo (ale tak w większości przypadków się wydaje ;)). Czy mógłby ktoś z Was rzucić na to okiem?

W przypadku nieznalezienia danego znaku w łańcuchu bazowym funkcja powinna zwrócić np. NULL - jak to zrealizować?

 
#include <iostream>

using namespace std;

char * znajdz(char * text, char alfa);	//deklaracja funkcji znajdz, zwracającej wskaźnik do drugiego wystąpienia znaku "alfa" w tekście

void program3() {
	//testowanie funkcji znajdz()

	char * message = "Litwo! Ojczyzno moja Ty jestes jak zdrowie. Ile Cie trzeba cenic ten tylko sie dowie, kto Cie stracil";
	char znak = 't';

	cout << "\ntekst bazowy: " << message;
	cout << "\nwyszukiwany znak: " << znak;
	cout << endl;
	cout << znajdz(message, znak);
}

char * znajdz(char * text, char alfa) {	//definicja funkcji znajdz, zwracającej wskaźnik do drugiego wystąpienia znaku "alfa" w tekście
	
	int licznik = 0;
	char * wsk = text;

	while (licznik<2)
	{
		wsk++;
		if ((* wsk == alfa) || (*wsk == alfa - 32))	//znak mały alfa, znak duży alfa - 32
		{
			licznik++;
		}
	}

	return wsk;
}
1
char *znajdz(char *text,char alfa)
  {
   int count=0;
   for(;(count<2)&&(*text);++text) count+=(tolower(*text)==alfa);
   return count==2?text-1:NULL;
  }
0
const char *strcichr(char const *a, char b)
{
    for (; *a; ++a) {
        int d = tolower(*a) - tolower(b);
        if (!d)
            return a;
    }

    return NULL;
}


const char * znajdz(const char * text, char alfa)
{
	text = strcichr(text, alfa);
	if (!text)
		return NULL;

	return strcichr(text + 1, alfa);
}

2
char * message = "Litwo! Ojczyzno moja Ty jestes jak zdrowie. Ile Cie trzeba cenic ten tylko sie dowie, kto Cie stracil";

Przypisanie literału znakowego do wskaźnika na non-const char jest nielegalne w C++ i nie powinno się kompilować. char const* message = ... albo char message[] = ...

Chciałem to jakoś ładnie po ceplusplusowemu zapisać, ale efekt jest co najwyżej średni:

char const* findSecond(char const* msg, char l){
	auto end = msg + strlen(msg);
	auto pred = [up = toupper(l), down = tolower(l)](char c){ return c == up || c == down; };
	for(int i = 0; i < 2; ++i){
		msg = find_if(msg, end, pred);
		if(msg != end) ++msg;
	}
	return msg == end ? nullptr : msg-1;
}

http://melpon.org/wandbox/permlink/KFdcCKc4OHhl3Vk0

1

@kq, jak parametr char * to zapomnij o cwplusplusowości ;P
Jeżeli już używamy funkcji standardowych to:

char *znajdz(char *text,char alfa) { return (text=strchr(text,alfa))?strchr(text+1,alfa):NULL; }

pojedynczy znak = to nie pomyłka.

Edit: dla dużą/małą

char *strchrext(char *text,char alfa) {  while((*text)&&(*text!=tolower(alfa))&&(*text!=toupper(alfa))) ++text;  return *text?text:NULL;  } 
char *znajdz(char *text,char alfa) { return (text=strchrext(text,alfa))?strchrext(text+1,alfa):NULL; }
1
template<typename It>
auto find_second(It begin, It end, typename iterator_traits<It>::value_type v) {
	return find_if(begin, end, [i = 0, v](auto chr) mutable { return chr == v && ++i >= 2; });
}

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