• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Napisz program otwierający plik tekstowy, wczytujący go znak po znaku do końca

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
0 głosów
2,163 wizyt
pytanie zadane 29 marca 2018 w C i C++ przez Archeon Początkujący (480 p.)

Witam,

Mam problem z tym zadankiem

Polecenie : Napisz program otwierający plik tekstowy, wczytujący go znak po znaku do końca, a następinie podający liczbę znaków w tym pliku.

Możecie mnie jakoś naprowadzić ?

 

Mój kod :

#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
int main()
{
    string linia;
    fstream plik;
 
    plik.open("plik.txt");
    if(plik.good() == true)
    {
        while(!plik.eof())
        {
            getline(plik, linia);
            cout << linia << endl; 
        }
		linia.length();
        plik.close();
    }
 
    system("PAUSE");
    return(0);
}

 

5 odpowiedzi

+1 głos
odpowiedź 29 marca 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)
std::getline wczytuje całą linię. Do wczytania pojedynczego znaku można użyć metody std::istream::get.
+1 głos
odpowiedź 29 marca 2018 przez mokrowski Mędrzec (158,660 p.)
edycja 29 marca 2018 przez mokrowski

1. Zastosuj strumień std::ifstream. On od razu otwiera plik w trybie do odczytu jeśli nie podasz innych flag.

2. Nie stosuj metody .open() na strumieniu pliku. Wystarczy że w konstruktorze podasz nazwę pliku. Jeśli tak to zrobisz, nie będziesz miał obowiązku wykonywania .close() na strumieniu pliku bo jego destruktor sam to zrobi. Ta filozofia obsługi nazywa się RAII.

3. Obiekt strumienia pliku ma przeciążoną metodę operatora bool w związku z tym test prawidłowości otwarcia to:
    if(file) {...
   .... bez zbędnego good() a już totalnie bez sensu jest == true. Złe jest także testowanie eof().

4. Jeśli pliku nie udało się otworzyć, na strumień std::cerr zaprezentuj komunikat i wykonaj: exit(EXIT_FAILURE). Aby to wywołanie zadziałało, dodaj nagłówek <csdtlib>. Wtedy dodaj także do ostatniego return w main()
return EXIT_SUCCESS;

5. Strumienie wejściowe domyślnie pomijają znaki nowej linii traktując je jako separatory danych. Aby strumień tego nie robił, stosuj na nim modyfikator std::noskipws.

Inicjuj zerem licznik znaków. Najlepszy typ do tych zastosowań to size_t Dodaj także zmienną pomocniczą typu char dla wczytywanego znaku.

6. Wykonuj w pętli while ciągłe wczytywanie znaku ze strumienia i inkrementuj licznik.

7. Na koniec zwróć na ekran komunikat z ilością wczytanych znaków.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <cstddef>

int main() {
    std::size_t licznik = 0;
    char znak;

    std::ifstream plik("plik.txt");

    if(!plik) {
        std::cerr << "Błąd otwarcia pliku.\n";
        exit(EXIT_FAILURE);
    }

    plik >> std::noskipws;
    while(plik >> znak) {
        ++licznik;
    }

    std::cout << "Plik zawiera " << licznik << " znaków.\n";

    return EXIT_SUCCESS;
}

 

0 głosów
odpowiedź 29 marca 2018 przez Beginer Pasjonat (22,110 p.)
To jest dobry program, dobre rozwiązanie. Z tym, że po wczytaniu każdej pojedynczej linii powinieneś od razu obliczyć jej długość - czyli ilość znaków, zapamiętać w zmiennej 'licznik', i dodawać znaki z kolejnych linii.

Czyli w programie musisz wprowadzić zmienną int licznik do sumowania znaków z kolejnych linii, na końcu wyswietlić jej wartość.

P.S. Wyświetlanie stringa linia jest zbędne.
1
komentarz 29 marca 2018 przez 0e85dc6eaf Dyskutant (8,840 p.)
W poleceniu jest "wczytujący znak po znaku", więc teoretycznie ktoś mógłby się tego przyczepić
komentarz 29 marca 2018 przez Beginer Pasjonat (22,110 p.)
Masz absolutną rację.

Najlepiej jak policzy znaki obiema metodami, porówna wartości, przedstawi je nauczycielowi.
komentarz 29 marca 2018 przez Archeon Początkujący (480 p.)
To jest polecenie z ksiązki "Szkoła Programowania" od Stehena Prata i zadanie robie tylko i wyłącznie dla siebie.

Wiec opcja pierwsza to wprowadzić int'a licznik, a opcja 2  std::istream::get. ? Jak jej użyć ?
komentarz 29 marca 2018 przez mokrowski Mędrzec (158,660 p.)
Typ int na licznik jest złym pomysłem. Planujesz obsługę ujemnych wartości licznika? Typ int obsługuje także wartości ujemne. Dla liczników, indeksów do tablic, wielkości obiektów, przeznaczony jest typ size_t. Poza tym w C i C++ operacje przepełnienia typów ze znakiem są oznaczane jako o niezdefiniowanym zachowaniu. Lepiej tego unikać a size_t jest typem bez znaku (unsigned).
0 głosów
odpowiedź 29 marca 2018 przez niezalogowany

Wiesz jak dostać się do rozmiaru linii więc wystarczy stworzyć nową zmienną i do niej dodawać w odpowiedniej pętli.

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

int main()
{
	using namespace std;
	string linia;
	fstream plik;
	size_t ile_znakow = 0;

	plik.open("funkcja.txt");
	if (plik.good())
	{
		while (!plik.eof())
		{
			getline(plik, linia);
			cout << linia << "[" << linia.length() << "]" << endl;
			ile_znakow += linia.length();
		}
		
		std::cout << "Liczba znakow: " << ile_znakow << "\n";
		plik.close();
	}
}

Można by się spierać czy zaliczać białe znaki i '\n'. Zależy co masz tam do zrobienia. Wtedy mógłbyś sprawdzać w danej linii ile jest liter za pomocą funkcji isalpha i pętli. Ewentualnie użyć gotowego rozwiązania z biblioteki algorithm (count_if). Wszystkie sposoby warto znać ;)

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <cctype>

int main()
{
	using namespace std;
	ifstream plik;
	size_t ile_znakow;

	plik.open("funkcja.txt");
	if (plik.good())
	{
		ile_znakow = count_if(istream_iterator<char>(plik), istream_iterator<char>(), isalpha); 
		cout << ilosc_znakow  << "\n";
		plik.close();
	}
}
0 głosów
odpowiedź 30 marca 2018 przez Archeon Początkujący (480 p.)
Dziękuję wszystkim za pomoc !

Podobne pytania

+1 głos
4 odpowiedzi 739 wizyt
pytanie zadane 11 września 2015 w C i C++ przez k222 Nałogowiec (30,150 p.)
0 głosów
1 odpowiedź 811 wizyt
+1 głos
3 odpowiedzi 1,137 wizyt
pytanie zadane 8 grudnia 2020 w C i C++ przez Radson09 Nowicjusz (190 p.)

93,440 zapytań

142,431 odpowiedzi

322,679 komentarzy

62,802 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...