Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Operacje na łańcuchach znaków, tablice znakowe

Ostatnio zmodyfikowano 2016-01-17 22:53
Autor Wiadomość
locust
Temat założony przez niniejszego użytkownika
Operacje na łańcuchach znaków, tablice znakowe
» 2015-12-19 22:21:20
Witam! Potrzebuję pomocy w pewnym zadaniu, oto jego treść:

Napisz funkcję: void str_zamien( char* tekst, char* stary_wzorzec, char* nowy_wzorzec);
realizującą operację zamiany w podanym tekście starego wzorca na nowy np.
<tekst> == "ala ma kota a ola ma asa"
<stary_wzorzec> == "ma"
<nowy_wzorzec> == "miala"
rezultat zamiany: "ala miala kota a ola miala asa"


Od razu podkreślam że nie wiem czy potrzebnie staram się zastępować gotowe funkcje np. strlen, memmove własnym kodem, w treści nie ma podane czy mogę używać biblioteki sting.h zatem starałem się tego unikać. Kompilator nie znajduje błędów, problem jest gdzieś w podstawie mojego zamysłu bo wynikiem "zamiany" jest (ostatnia litera starego wzorca * dlugosc tekstu + pierwsza litera nowego wzorca * długość tegoż). Mój mózg już dzisiaj nie działa, dlatego aż wstyd na samą myśl jakie głupoty w tym kodzie są, a ja ich nie widzę... trudno. :)

Moje wypociny na ten temat:

C/C++
#include <iostream>
using namespace std;

char tekst[ 100 ], stary[ 100 ], nowy[ 100 ];

void str_zamien( char * tekst, char * stary, char * nowy ) {
    int licz_t, licz_s, licz_n, i( 0 ), miejsce, pom;
    // zliczanie zamiast strlen
    while( tekst[ i ] != '\0' ) {
        if( tekst[ i ] = stary[ 1 ] ) miejsce = i;
       
        i++;
    } licz_t = i; i = 0;
    while( stary[ i ] != '\0' ) {
        i++;
    } licz_s = i; i = 0;
    while( nowy[ i ] != '\0' ) {
        i++;
    } licz_n = i; i = 0;
   
   
    if( licz_n > licz_s ) {
        for( pom = licz_t + licz_n; pom > miejsce + licz_n; pom-- ) tekst[ pom ] = tekst[ pom - licz_n ]; // przesuniecie zamiast memmove
       
        for( int i = miejsce; miejsce < pom; miejsce++ ) { // zamiana zamiast memcpy (chyba ;p)
            int j = 0;
            tekst[ miejsce ] = nowy[ j ];
            j++;
        }
        cout << tekst;
       
    } else cout << "sie zrobi"; // analogicznie zmienic to co wyzej, dopisze gdy jakos uda sie to poprawnie odpalic
   
   
}

int main()
{
    cout << "Wpisz zdanie\n";
    gets( tekst );
    cout << "Wpisz stary wzorzec\n";
    gets( stary );
    cout << "Wpisz nowy wzorzec\n";
    gets( nowy );
    str_zamien( tekst, stary, nowy );
    system( "pause" );
    return 0;
}


Jeśli rozczytaliście jakoś ten kod to proszę o pomoc i rady jak to napisać poprawnie. Z góry dziękuję! Pozdrawiam!
P-142162
carlosmay
» 2015-12-20 00:48:17
if( tekst[ i ] = stary[ 1 ] ) miejsce = i;
 '=' to nie operator porównania.
Dlaczego przy szukaniu do porównania wybrano drugi znak ze starego wzorca?
Sposób raczej zły, bo znaki powtarzają się z zdaniu, a nie wykrywa czy w znalezionym miejscu
następne znaki też są zgodne ze starym wzorcem.
P-142166
locust
Temat założony przez niniejszego użytkownika
» 2015-12-20 01:15:23
Hah, tak jak myślałem i tak jak jest w tym ifie jakieś kompletne głupoty miałem w kodzie ehh... przynajmniej ostrzegałem. ;p
I faktycznie to moje szukanie jest do niczego, dzięki za uwagę... hmmm, pokombinuję jeszcze żeby to przerobić, ale na wszelki wypadek raczej zrobię też wersję ze string.h. ;) Możliwe że jeszcze jutro (yyy tzn. dzisiaj) się tutaj odezwę.
P-142168
locust
Temat założony przez niniejszego użytkownika
» 2016-01-17 21:26:55
Witam ponownie! Potrzebuję tym razem pomocy w przerobieniu wyżej opisanego zadania tak aby użyte zostały tablice dynamiczne. Wersja programu mniej ambitna, bo z wbudowanymi funkcjami, ale dla odmiany działająca, problem pojawia się w zestawieniu dynamiczne + gets(). Problem którego kompletnie nie rozumiem... 
Oto mój kod:
C/C++
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;

char * tekst, * stary, * nowy;
int roz, roz_s, roz_n;

void str_zamien( char * tekst, char * stary, char * nowy ) {
    char * miejsce;
    do {
        miejsce = strstr( tekst, stary );
        if( miejsce ) {
            memmove( miejsce + roz_n, miejsce + roz_s, strlen( miejsce + roz_s ) + 1 );
            memcpy( miejsce, nowy, roz_n );
        }
    } while( miejsce );
   
    cout << tekst << endl;
}

int main()
{
    cout << "Dlugosc zdania: \n";
    cin >> roz;
    tekst = new char[ roz + 1 ];
    cout << "Dlugosc starego wzorca: \n";
    cin >> roz_s;
    stary = new char[ roz_s + 1 ];
    cout << "Dlugosc nowego wzorca: \n";
    cin >> roz_n;
    nowy = new char[ roz_n + 1 ];
    cout << "Wpisz zdanie\n";
    gets( tekst );
    cout << "Wpisz stary wzorzec\n";
    gets( stary );
    cout << "Wpisz nowy wzorzec\n";
    gets( nowy );
    str_zamien( tekst, stary, nowy );
    system( "pause" );
    delete[] tekst;
    delete[] stary;
    delete[] nowy;
    return 0;
}

Sytuacja wygląda tak, że konsola wyświetla komendy odnoszące się do długości oraz pobiera wskazane wartości. Niestety po wyświetleniu "Wpisz zdanie" program zamiast uruchomić gets(tekst) przeskakuje do wyświetlenia "Wpisz stary wzorzec", a po tym ku zaskoczeniu poprawnie uruchamia funkcję gets(stary). Na czym polega ten problem że jeden gets nie działa, a drugi tak? Bardzo proszę o pomoc.    
P-143694
carlosmay
» 2016-01-17 22:30:57
Po wczytaniu zmiennej za pomocą strumienia std::cin w buforze strumienia pozostaje znak nowego wiersza
'\n'
.
Jest on automatycznie wczytany przez gets(), a że znak
'\n'
 kończy wczytywanie, to przechodzi do następnej instrukcji.
Dodaj getchar() lub std::cin.get() przed pobieraniem z klawiatury pierwszego zdania.

Swoją drogą skup się na C++ lub C.

P-143703
locust
Temat założony przez niniejszego użytkownika
» 2016-01-17 22:47:11
Dzięki wielkie! Po cin'ach wyczyściłem bufor za pomocą cin.sync() i to wystarczyło. Działa. :) Pozdrawiam serdecznie!
P-143707
carlosmay
» 2016-01-17 22:53:04
Po cin'ach wyczyściłem bufor za pomocą cin.sync()
std::cin.sync();
 nie wszędzie działa.
Lepiej użyć
std::cin.ingnore()
.
P-143708
« 1 »
  Strona 1 z 1