Zliczanie ilosci podanego znaku w pliku tekstowym

0

Witam, bawię się plikami tekstowymi w C++, stworzyłem już kod w którym program zlicza mi ilość znaków w pliku tekstowym, natomiast chciałbym go edytować w taki sposób żeby zliczało mi ilość konkretnych znaków, które ja podaje. Czy jest ktoś w stanie mi pomóc jak go edytować żeby działało? Wszystkie moje próby albo pokazywały mi wynik 783400 albo po prostu 0. Bardzo proszę o pomoc.

#include <iostream>
#include <fstream>

using namespace std;

int znaki();

int main()
{
    cout << "STATYSTYKA PLIKU" << endl;
    cout << "Ilosc znakow: " << znaki() << endl;

    return 0;
}

int znaki()
{
    int iloscznakow;

    ifstream plik("plik.txt");
    for(iloscznakow=0; plik.get()!=EOF; ++iloscznakow) {}

    return iloscznakow;
}

0
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

char znak_szukany;

int znaki();
int szukany();

int main()
{
    cout << "Ilosc znakow: " << znaki() << endl;
    cout << "Ilosc znakow '" << znak_szukany << "' : " << szukany();

    return 0;
}

int znaki()
{
    ifstream plik;
    string linia;
    int licznik;
    plik.open("plik.txt");
    if(!plik.good())
    {
        cout << "\nNie znaleziono pliku!" << endl;
        plik.close();
    }
    getline(plik,linia);

    plik.close();

    return linia.length();
}

int szukany()
{
    ifstream plik;
    string linia;
    int licznik;
    cout << "Podaj znak do znalezienia: ";
    cin >> znak_szukany;
    plik.open("plik.txt");
    if(!plik.good())
    {
        cout << "\nNie ma pliku!" << endl;
        plik.close();
    }
    plik >> linia;
    for(int i=0;i<linia.length();i++)
    {
        if(linia[i]==znak_szukany)
            licznik++;
    }
    plik.close();
}

Tutaj próbowałem innym sposobem.

0

Musisz inkrementować wartość tylko jeśli wczytany znak jest równy temu szukanemu.

0

Pytania: 1) co dokładnie jest w pliku 2) jakie znaki wprowadzasz.

2
    plik >> linia;
    for(int i=0;i<linia.length();i++)
    {
        if(linia[i]==znak_szukany)
            licznik++;
    }

Nie wczytujesz tak całego pliku, tylko pierwszy wyraz z tego pliku. I tylko w nim zliczasz.

Przy okazji: dziel kod na funkcje w taki sposób, aby funkcja realizująca jakąś funkcjonalność (np liczenie znaków) nie odpowiadała za inne rzeczy (np. za wyświetlanie rzeczy na konsoli, albo za wczytywanie danych od użytkownika). Użyj do tego wartości zwracanych i parametrów funkcji.
https://en.wikipedia.org/wiki/Single-responsibility_principle

0

Poprawiłem kod, że zlicza już znaki z każdej linii. Zliczanie znaków działa już poprawie, natomiast zliczanie konkretnego wprowadzanego przez użytkownika znaku nadal świruje i pokazuje wysokie liczby.. Dodam tylko, że zliczanie wprowadzanego przez użytkownika znaku działa poprawie ale jak nie ma funkcji zliczania wszystkich znaków... W czym jest problem ktoś byłby w stanie mi poprawić ten kod?

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int znaki();
int szukany();

int main()
{
    cout << "STATYSTYKA PLIKU" << endl;

    cout << "Ilosc znakow: " << znaki() << endl;
    cout << "Ilosc szukanych: " << szukany() << endl;

    return 0;
}

int znaki()
{
    ifstream plik;

    string linia;
    int licznik;

    plik.open("plik.txt");

    if(!plik.good())
    {
        cout << "\nNie ma pliku!" << endl;
        plik.close();
    }
    while(!plik.eof())
    {
        string pomocniczy;
        getline(plik,pomocniczy);
        linia+=pomocniczy;
    }

    plik.close();

    return linia.length();
}

int szukany()
{
    ifstream plik;

    string linia;
    int licznik;
    char znak_szukany;
    cout << "Podaj znak szukany: ";
    cin >> znak_szukany;

    plik.open("plik.txt");

    if(!plik.good())
    {
        cout << "\nNie ma pliku!" << endl;
        plik.close();
    }

    while(!plik.eof())
    {
        string pomocniczy;
        getline(plik,pomocniczy);
        linia+=pomocniczy;
    }

    for(int i=0;i<linia.length();i++)
    {
        if(linia[i]==znak_szukany)
            licznik++;
    }

    plik.close();

    return licznik;
}

2

Nie inicjujesz licznika żadną liczbą, więc mogą tam być śmieci po czym go inkrementujesz.

string linia="";
int licznik=0;
0

Dziękuję bardzo Botek!

1

A teraz masz dla porównania:

int count_chars(std::string_view file_name, char sought)
{
    int ret = 0;
    std::ifstream file(file_name);
    char c;
    while(file >> c)
        if(c == sought)
            ret++;
    return ret;
}

Bez obsługi nieistniejącego pliku, ale ogólna zasada wydaje się zrozumiała. (a tak na marginesie to count_chars też nie powinno być raczej odpowiedzialne za otwieranie pliku, ale to inna sprawa)

2

Można też skorzystać z std::istream_iterator + std::count

auto result = count(istream_iterator<char>{file}, istream_iterator<char>{}, sought);

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