Operacje na stringach

0

Witam!
Chciałabym napisać program, który wstawia dowolny ciągu znaków, przekazanego jako parametr funk-
cji, w miejsce k w napisie źródłowym.

Oto kod z maina:

int main(int argc, char * argv[]);
{ 
int k = atoi(argv[3]);
cout << "atoi(argv[3])" << k << endl;
string text1(argv[1]);
string text2(argv[2]);
char *funkcja = wstaw(argv[1],argv[2],k);
string funkcja2 = wstaw1(text1,text2,k); 
}

Szczerze powiedziawszy średnio rozumiem treść zadania, czy mógłby mi ktoś napisać jakąś podpowiedź? Nie chcę rozwiązania tylko jakiejś wskazówki. No bo jak mam wstawić jakieś znaki w k skoro k jest typu int? Wiem że trzeba chyba zrobić jakąś konwersję ale nie bardzo mi to wychodzi :(
Dodam że jestem początkująca..
Pozdrawiam :)

0

Musisz wstawić text2 w text1 na pozycji k? No to jeżeli używasz C++ i klasy std::string to masz do tego gotową metodę: std::string::insert (<- kliknij).

0

Stworz pomocniczy string, przekopiuj do niego znaki od 0 do k, nastepnie do niego dopisz fragment ktory ma byc wklejony w dane miejsce, a nastepnie do tego stringa doklej resztę stringa pierwszego i zwróc wartość pomocniczego stringa

0

Ciąg wstawiany zastępuje, czy przesuwa znaki?
Jeśli zastępuje, to najpierw sprawdziłbym czy dla n będącego długością ciągu wstawianego, k + n jest większe od rozmiaru ciągu nadpisywanego. Jeśli nie, wystarczy skopiować obszar pamięci zajmowany przez ciąg zastępujący na obszar wskazywany przez wskaźnik na ciąg nadpisywany, przesunięty o k - 1. Jeżeli przekracza, to będziesz musiał zaalokować nową przestrzeń o rozmiarze k + n i dopiero wtedy kopiować. Pamiętaj o bajcie zerowym.
Jeśli przesuwa, to musisz zaalokować nową przestrzeń o rozmiarze m + n + 1, gdzie m i n to długości obu ciągów, następnie skopiować obszar pamięci o rozmiarze k - 1 z ciągu nadpisywanego, dokleić ciąg zastępujący, i w końcu dane z ciągu nadpisywanego od pozycji k do końca. Pamiętaj o bajtach zerowych.

W przypadku std::string nie widzę sensu w babraniu się kopiowaniem, skoro jest insert().

0

Tylko tak jak napisał Sarrus. To prawdopodobnie jest jakieś zadanie, dlatego zastanawia mnie w ogóle fakt, że są używane tutaj obiekty klasy string, chociaż jeżeli jest to dozwolone, to nie musi alokować większej przestrzeni dla stringa, bo ta klasa robi to automatycznie ;-)

0

Ja tam widzę dwie funkcje. Jedna zwraca std::string, druga cstring. Moja propozycja dotyczy cstringa. W zabawie na std:string nie widzę tutaj sensu, gdyż nie po to są klasy żeby nie korzystać z ich metod. Jeśli jednak z jakiegoś powodu nie wolno korzystać z insert() (np. "widzimisie" wykładowcy), to i tak trzeba to zrobić na wyciągniętym z std::string cstringu, lub udawać że się robi coś twórczego przerzucając znaczki między tablicami, bo międlenie tego na metodach to przerost formy nad treścią.

0
MJay napisał(a)

Stworz pomocniczy string, przekopiuj do niego znaki od 0 do k, nastepnie do niego dopisz fragment ktory ma byc wklejony w dane miejsce, a nastepnie do tego stringa doklej resztę stringa pierwszego i zwróc wartość pomocniczego stringa

Ale właśnie jak mam przekopiować do stringa znaki od 0 do k skoro k jest typu int? Mam zrobić jakąś konwersję? Nie wiem, chyba się w tym gubię :( Proszę kogokolwiek o radę...

0

k to jest pozycja - indeks przecież... Tej liczby nie masz wstawiać, ona określa gdzie wstawić i nie trzeba tu nic konwertować... Nie rozumiesz treści zadania nawet...

0

@joaannaan, pozwól, że wyjaśnię na przykładzie.
text_zrodlowy = "Ala ma kota"
text_do_wstawienia = "psa, chomika, świnię i "
oraz k = 7
Teraz wstawmy text_do_wstawienia do text_zrodlowy na miejscu k:
"Ala ma psa, chomika, świnię i kota"

Kapisz?

0

std::string możesz potraktować jak tablicę. Nie będzie miał nic przeciwko temu. Indeksy tablicy mogą być intami. Zatem std::string[5] zwróci Ci szósty element (znak). Wystarczy objąć to jakąś zgrabną pętlą.

0

Dziękuję, już bardziej to rozumiem :)

Sarrus napisał(a)

k to jest pozycja - indeks przecież... Tej liczby nie masz wstawiać, ona określa gdzie wstawić i nie trzeba tu nic konwertować... Nie rozumiesz treści zadania nawet...

Sorki, ale dopiero zaczynam programować więc wiele rzeczy jeszcze nie rozumiem, zresztą napisałam już w pierwszym poście że nie wiem za bardzo o co chodzi... Bardzo chcę się nauczyć tego języka i przykro mi że ktoś na samym początki już mi pojeżdza ! Pozdrawiam.

0
joaannaan napisał(a)

Sorki, ale dopiero zaczynam programować więc wiele rzeczy jeszcze nie rozumiem, zresztą napisałam już w pierwszym poście że nie wiem za bardzo o co chodzi...

Ja nadal nie rozumiem tego zadania. Nie wyjaśnione jest czy znaki w ciągu docelowym mają być nadpisane, czy przesunięte. Czyli przy ciągach Ala ma owsiki" i "kredyt", przy k = 7wynikiem ma byćAla ma kredytowsikiczyAla ma kredyt''...

joaannaan napisał(a)

Bardzo chcę się nauczyć tego języka i przykro mi że ktoś na samym początki już mi pojeżdza ! Pozdrawiam.

Silna musisz być. Docinki ignorować. C-Jedi umieć musi to. Dziewczyny nawet.

0

@up, stawiałabym na to pierwsze. Intuicyjnie, wstawić ciąg znaków w ciąg znaków... Wydaje mi się bardziej prawdopodobna.
@joaannaan, nie masz może oryginalnej treści zadania?

0
aurel napisał(a)

stawiałabym na to pierwsze. Intuicyjnie, wstawić ciąg znaków w ciąg znaków... Wydaje mi się bardziej prawdopodobna.

Jeśli to są początki nauki programowania, to bardzo możliwe. Nadpisanie jest łatwiejsze niż wstawienie, więc pewnie wykładowca nie chce mieszać studentom w głowach.

0

Nie rozumiem sensu takich zadań. W C++ jest klasa std::string, która powstała po to, żeby nie pisać własnej obsługi łańcuchów znakowych. Kombinowanie jakichś własnych funkcji zamiast używania tych z biblioteki standardowej to niepotrzebnie stracony czas i w zasadnie zero nauki języka. (Bo ważnym elementem nauki C++ jest biblioteka standardowa)

Potem taki "nauczony" nie używa stringów i nie zna biblioteki, bez sensu.

0
Endrju napisał(a)

Nie rozumiem sensu takich zadań. W C++ jest klasa std::string, która powstała po to, żeby nie pisać własnej obsługi łańcuchów znakowych.

Ja też nie, ale popatrzmy na to z innej strony. Może celem zadania nie jest nauka wykorzystywania std::string, lecz operowania na tablicach. Ciągi znaków mogą być wybrane ze względu na to, że efekt działania można łatwo zobrazować, w prosty sposób. Oczywiście, lepiej w takim przypadku zlecić zadanie na cstringach, ale jak sam wskazałeś, nie po to w C++ istnieje std::string żeby dłubać w cstringach.
Nadal jednak zastanawia mnie obecność dwóch funkcji w przytoczonym kodzie.

0

Nie rozumiem sensu takich zadań. W C++ jest klasa std::string, która powstała po to, żeby nie pisać własnej obsługi łańcuchów znakowych.

Mi się wydaje, że w tym zadaniu chodzi o megastycznie trudną dla początkującego sztuczkę - przekazanie tablicy do funkcji.

0

Oto cała tresć zadania:

Zaprojektować, zaimplementować i przetestować funkcje służące do:
• wstawienia dowolnego ciągu znaków, przekazanego jako parametr funk-
cji, w miejsce k w napisie źródłowym
//...

 
        int k = atoi(argv[3]);
        string text1(argv[1]);
        string text2(argv[2]);
        char* funkcja = wstaw(argv[1],argv[2],p);
        string funkcja1 = wstaw1(text1,text2,k);
        cout << "Wstawienie dowolnego ciagu znakow w miejsce p: \n";
        cout << funkcja << "\n";
        cout << funkcja1 << "\n";
        //...

• wstawienia dowolnego znaku, przekazanego jako parametr funkcji, co
n znaków w napisie źródłowym
//...

 
int p = atoi(argv[3]);
string str1(argv[1]);
                       
string ch;
ch.assign(1,argv[2][0]);
char * dest = wstaw_n(argv[1],argv[2], p);
string dest1 = wstaw1_n(str1,ch, p);
cout << "Wstawienie dowolnego znaku co n znakow: \n";
cout << dest << "\n";
cout << dest1 << "\n";
//...

• zamiany białych znaków w napisie źródłowym na dowolny inny znak,
przekazany jako parametr funkcji.

 
         //...
         string str1(argv[1]);
         char * dest = zamien(argv[1],argv[2][0]);
         string dest1 = zamien1(str1,argv[2][0]);
         cout << "Zamiana bialych znakow na dowolny inny znak: \n";
         cout << dest << "\n";
         cout << dest1 << "\n";
         //...

Ciągi znaków odebrać jako parametry wywołania programu.
Funkcje zaimplementowane powinny być na dwa sposoby: z wykorzystaniem
tablicy znaków char * oraz typu string.

0

Co do zamiany białych znaków (akurat mam pod ręką bo używałem):

  std::string t("t e s t");
  char replace = '-';
 
  std::replace_if(t.begin(), t.end(), std::bind2nd(std::less<char>(), '!'), replace);

http://ideone.com/i4IaJ

Podobnie zadziała z tablicą charów.

0

Myślę, że trzeba się tu skupić na tablicach znaków. Zdefiniujmy dwa indeksy:
k - czyli pozycja w text1 "aa aa aa"
i - czyli pozycja w text2 "bb"

dla
char text1[] = "aa aa aa"
char text2[] = "bb"
k=3
i = 0 (zawsze)
będzie:
text1[k] = text2[i]
czyli
text1[3] = text2[0]

Teraz wystarczy jednocześnie zwiększać k oraz i

Myślę, że dość jasno przedstawiłem koncepcję ;]

0

Jak dla mnie to przedstawiłeś ją tak, żeby ona w przyszłości się myliła, że

text1[k] = text2[i]

przekopiuje jej cały tekst. Prawdopodobnie Ty wiesz co to robi, ale należałoby to wytłumaczyć początkującemu, że jeżeli chce przekopiować całą tablicę to powinna zrobić to tak:

//przede wszystkim, na pozycji k mamy zaczac wklejanie, czyli jeżeli ciąg jest indeksowany od 0, to trzeba k zmniejszyć o jeden
k--; // dla k == 3, k będzie wskazywało na pozycję trzecią czyli text1[2]
//następnie albo używamy funkcji z biblioteki <cstring>
strcpy(text1 + k, text2);
//lub tworzymy własną funkcję
void foo(char* txt1, char txt2[], int poz) // nie ma różnicy w deklaracji tych agrumentów funkcji
{
    int i = 0;
    while((txt[k++] = *(txt2 + i++));
}
0

Pierwszy wynik w wyszukiwarce
http://www.egrafik.pl/kurs-c-plus-plus/4.4.php

0

Witajcie,

ponieważ pytanie moje dotyczy podobnego problemu to podepnę się pod ten temat.

Próbuję zrobić coś takiego: zdefiniować obiekt, któremu można nadać nazwę. Próbowałem zrobić to w taki sposób, ale nie działa.

 class CEmployee
{
protected:
	int empID;
	string Name
public:
        CEmployee::CEmployee(string name);
}

CEmployee::CEmployee(string name)
{
   Name = name
}

CEmployee* w1 = new CEmployee("Pracownik");

Domyślam się, że w moim toku myślenia jest jakiś błąd, ale przeszukałem już trochę informacji w sieci, ale nie rozwiązało to mojego kłopotu. Może źle rozumiałem, może czegoś nie znalazłem, nie wiem... W każdym razie wielkie dzięki za pomoc w rozwiązaniu problemu.

0

brak średnika po klamrze zamykającej klasę, poza tym wydaje się być ok.

0
#include <string>
 class CEmployee
{
protected:
        int empID;
        string Name;
public:
        CEmployee::CEmployee(string name);
};
 
CEmployee::CEmployee(string name)
{
   Name = name;
}
 
CEmployee* w1 = new CEmployee("Pracownik"); 

Dodałem jeszcze include'a na "string", ale to też nie pomaga i cały czas wywala błąd - kompilator nie rozpoznaje typu "string" i traktuje go jako nazwę zmiennej.

1

Nie wiedziałem, że to cały plik jaki zapisałeś. Musisz albo na początku dodać using namespace std; albo przed każdym string dodać std::string

0

Ah, znalazłem rozwiązanie i zgubiłem w jednym pliku nagłówkowym "using namespace std". Faktycznie było to trywialnie proste, ale cóż, nie wszystko się zobaczy od razu. Dzięki za pomoc!

0

Od tego jest forum ;]

0

Dziękuję bardzo za podpowiedzi i wskazówki, bardzo mi pomogliście :)

Pozdrawiam :)

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