Dziwne działanie programu – zadanie ze wskaźników

0

Mam takie zadania do zrobienia. Ponizszy program działa ale nie pokazuje żadnych wynikow w konsoli. Nie rozumiem gdzie popełniłem błąd.

zapisać i przetestować w programie własne funkcje:

  1. int len(const char* napis) zwracającą długość danego napisu napis, np. len("abc") -> 3,
  2. int cmp(const char* napis1, const char* napis2) porównującą leksykograficznie dwa napisy, zwracającą 0 jeśli napisy są identyczne, -1 jeśli napis1 jest wcześniejszy niż napis2, +1 jeśli napis1 jest późniejszy, np. cmp("bbc", "abcd") -> 1, cmp("abcde", "b") -> -1,
  3. int norepdig(const char* napis) zwracającą ilość niepowtarzających się cyfr, występujących w napisie napis, np. norepdig("ab3c4d3a1") -> 2.
#include <iostream>
#include <cmath>

using namespace std;

int  len(const char* napis)
{
int i;
for (i = 0; napis!='\0'; ++i);
return i;
}

int  cmp(const char* napis1, const char* napis2)
{
int i;
for(i=0;i<len(napis1);i++)
if (napis1!=napis2) break;
if(i==len(napis1)) return 0;
if (napis1>napis2) return 1;
return -1;
}

int  norepdig(const char* napis)
{
    int temp=len(napis),*tab=new int[temp],i,j;
    for(i=0;i<temp;i++) tab[i]=0;
    for(i=0;i<temp;++i)
    {
            for(j=0;j<i;++j)
                    if(napis[i]==napis[j]) break;
            tab[j]++;
    }
    for(i=0,j=0;i<temp;i++) if(tab[i]==1) j++;
    delete[] tab;
    return j;

}

int main()
{
const char *napis= "blabla";
const char *napis1= "abcdef" ;
const char *napis2= "qwerty";
cout << endl; len(napis) ; cout << endl;
cout << endl; cmp(napis1,napis2) ; cout << endl;
cout << endl; norepdig(napis) ; cout << endl;


return 0;
}
0

Tutaj:

cout << endl; len(napis) ; cout << endl;
cout << endl; cmp(napis1,napis2) ; cout << endl;
cout << endl; norepdig(napis) ; cout << endl;

tylko wykonujesz podane funkcje, a nie wyświetlasz ich wyników. Powinieneś dodać cout, żeby wyglądało tak:

cout << endl; cout << len(napis) ; cout << endl;
cout << endl; cout << cmp(napis1,napis2) ; cout << endl;
cout << endl; cout << norepdig(napis) ; cout << endl;

A najlepiej zapisuj każdą instrukcję w oddzielnej linii – między innymi łatwiej zobaczyć wtedy takie błędy.

0

taa zauwazylem to zaraz po napisaniu tego postu, jednakze rezultat jest ten sam- nic nie wyswietla.

Moze ktos uruchomic ten kod u siebie? Moze błąd nie tkwi w treści instrukcji.

0

Nie jestem specjalistą od C++, wręcz dawno miałem z nim styczność, ale:

int  len(const char* napis)
{
    int i;

Zawsze inicjuj zmienną przy deklaracji! int i = 0; Spotkałem się z miejscami, w których problematycznym było nadawanie wartości początkowej (m.in. było kilka możliwych), ale sądzę, że lepszym rozwiązaniem byłaby wtedy zmiana projektu programu.

    for (i = 0; napis!='\0'; ++i);
    return i;
}

No a tutaj brak po prostu jakiejkolwiek instrukcji przed średnikiem dla instrukcji for. Usuń średnik po for i dodaj klamry. Uważam, że zawsze należy dodawać klamry w takich instrukcjach jak for oraz if. Inna sprawa, że ten for nie wygląda sensownie...

if (napis1!=napis2) break;
if(i==len(napis1)) return 0;
if (napis1>napis2) return 1;
return -1;

Klamry!

int temp=len(napis),*tab=new int[temp],i,j;

Najlepiej rozdziel na dwie definicje (w oddzielnych liniach).

    for(i=0;i<temp;i++) tab[i]=0;

Brak klamer.

            for(j=0;j<i;++j)
                    if(napis[i]==napis[j]) break;
            tab[j]++;

Nie ma klamer, a nie analizowałem funkcji, więc nie wiem, czy tab[j]++ powinno wykonać się w środku (czyli jest błąd) czy po instrukcji for (czyli błędu nie ma). Gdyby klamry były, byłaby większa jasność.

    for(i=0,j=0;i<temp;i++) if(tab[i]==1) j++;

Rozdziel najlepiej na odrębne linijki.

To tak na szybko. Nie analizowałem funkcji. Jeśli nadal nie będzie działać, pisz.

1

@Silv: nie przesadzaj z tymi klamrami. Grupuje się instrukcje wtedy, kiedy wymagają zgrupowania, a każdy normalny koder widzi, że jak klamer nie ma, to pętla/warunek ma wykonać jedną instrukcję, a jak są, to że jedną lub kilka.

Natomiast OP ma braki w wiedzy, a zmuszanie go do pisania wszędzie klamer niczego nie zmieni.


Co do kodu:

int i;
for (i = 0; napis!='\0'; ++i);

Skoro używasz zmiennej wyłącznie jako iterator pętli, to nie musisz deklarować jej wcześniej – wystarczy prosto w nagłówku pętli, od razu inicjalizując jej wartość początkową:

int len(const char* napis)
{
  for (int i = 0; napis != '\0'; ++i);
    return i;
}

W dalszym ciągu ta pętla nie ma raczej sensu.

Poniższe też jest dziwne:

cout << endl; len(napis) ; cout << endl;
cout << endl; cmp(napis1,napis2) ; cout << endl;
cout << endl; norepdig(napis) ; cout << endl;

Przecież i tak chcesz wyświetlić kilka danych, więc zamiast średników/cout wystarczy operator:

cout << endl << len(napis) << endl;
cout << endl << cmp(napis1, napis2) << endl;
cout << endl << norepdig(napis) << endl;

Tyle że w dalszym ciągu robisz po dwie puste linie przerwy pomiędzy danymi – za dużo tych endl:

cout << len(napis) << endl;
cout << cmp(napis1, napis2) << endl;
cout << norepdig(napis) << endl;
0

Ja dam ci wędkę nie rybę :)
a) Użyj debbuera i idź krok po koku, przykład
b) gtest i gmock do testów, https://github.com/google/googletest/blob/master/googlemock/docs/ForDummies.md http://www.bogotobogo.com/cplusplus/google_unit_test_gtest.php
c) Tragiczne formatowanie w eclipse ctrl+shift+ f lub w vs ctrl + k a później ctrl+ d dla autoformatowania
d) Dobra mały tip, https://pl.wikibooks.org/wiki/C/strlen

BTW. ty bardziej u robisz C niż C++ bo w c++ masz string.

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