Program wczytujący dowolny plik i zamieniający w nim małe litery na duże.

0

Napisz program, który wczyta plik z dowolnym tekstem, a następnie zamieni w nim wszystkie małe litery na duże i go zapisze.

Jak się za to zabrać? -> Chodzi o to, że jakiś mój plik czy na serio dowolny plik?

Mam taką funkcję:

const char d = 'A' - 'a';

char toUpper(char c)
{
	if ('a' <= c && c <= 'z') return c + d;
	else return c;
}

Jak ją wykorzystać, chodzi mi o to jak dostarczać do niej znak, po znaku z pliku, bo nie potrafię tego zrobić. Jak odczytywać znak po znaku z pliku nieważnego jaki by on nie był?

3

Do operacji na plikach użyj std::fstream. Funkcji toUpper nie musisz pisać, już taka jest - std::toupper w <cctype> albo w <locale>. Do transformacji zawartości pliku użyj std::transform. Ten program to kilka linijek.

0
Endrju napisał(a):

Ten program to kilka linijek.

Próbuję tak, czemu mam błędy?

#include<iostream>
#include<algorithm>
#include<conio.h>
#include <fstream>
#include<string>
using namespace std;

const char d = 'A' - 'a';

char toUpper(char c)
{
	if ('a' <= c && c <= 'z') return c + d;
	else return c;
}

using namespace std;

int main()
{
	fstream plik;
	plik.open("dane.txt", ios::in);
	if (plik.good())
	{
		string napis;
		cout << "Zawartosc pliku:" << endl;
		do
		{
						getline(plik, napis);
						for (int i = 0; i < napis.length; i++)
						{
							cout<<toUpper(napis[i]);
						}
			
		} while (!plik.eof());
		plik.close();
	}
	else cout << "Error! Nie udalo otworzyc sie pliku!" << endl;


	_getch();
}
1
        string napis;
        do
        {
                        getline(plik, napis);
                        transform(napis.begin(), napis.end(), napis.begin(), ::tolower);
                        cout << napis << endl; 
        } while (!plik.eof());
        plik.close();

W miarę eleganckie rozwiązanie, ograniczające liczbę niepotrzebnych pętli z http://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/
Nie zapomnij zaincludować

#include <algorithm>
#include <string>

I zawsze pisz o jakie błędy chodzi, bo tak tylko rzuciłem przykład

3

Tzn. chodziło mi o to, że to jedna linijka jest:

std::transform(std::istreambuf_iterator<char>(input),
               std::istreambuf_iterator<char>(),
               std::ostreambuf_iterator<char>(output),
               ::tolower);	

http://ideone.com/QdvqJ7

Tylko oczywiście zamiast input i output trzeba podłożyć ten plik.

Ten kod jest ładny, ale przetwarzanie w ten sposób chyba nie jest do końca najlepszym rozwiązaniem, a przynajmniej nie zawsze. Załadowanie pliku do pamięci (do stringa, wektora) i transformacja tego będzie zdaje się szybsza. Jednak w tego typu zadaniach to rozwiązanie jest bardzo elegenackie. (Już i tak użyłem Xstreambuf_iterator zamiast Xstream_iterator co zdaje się ma być "lepsze" dla takiej niskopoziomowej operacji).

0
Endrju napisał(a):

Ja mam teraz taki kod:

#include<iostream>
#include<algorithm>
#include<conio.h>
#include <fstream>
#include<string>
#include <sstream>

using namespace std;

const char d = 'A' - 'a';

char toUpper(char c)
{
	if ('a' <= c && c <= 'z') return c + d;
	else return c;
}

using namespace std;

int main()
{
	fstream plik;
	plik.open("dane.txt", ios::in);
	if (plik.good())
	{
		string napis;

		do
		{
			getline(plik, napis);


			transform(napis.begin(), napis.end(), napis.begin(), toUpper);
			cout << napis << endl;
			


		} while (!plik.eof());
		
		fstream plik("plik.txt", ios::out); {
			plik << napis;
		}

		plik.close();
	}
		
	else cout << "Error! Nie udalo otworzyc sie pliku!" << endl;


	_getch();
}

Ktoś wie dlaczego, nie zapisuje do pliku, tego napisu, tylko powstaje pusty plik? A wyświetla dobrze?

0

Tekst wysyłasz tylko na cout, w Twoim przykładzie nie było nic o zapisywaniu do pliku.
Zamiast

cout << napis << endl;

wewnątrz pętli dawaj plik_wyjsciowy << napis << endl;

. Oczywiście wcześniej otwierając plik do zapisu.

A to:
```cpp
        fstream plik("plik.txt", ios::out); {
            plik << napis;
        }

Nic nie daje, ponieważ po przejściu pętli, powinieneś mieć pusty string. Musisz zapisywać na bieżąco wewnątrz poprzedniej pętli.

Najlepiej wykorzystaj przykład @Endrju
Musisz tylko otworzyć 2 pliki, jeden do odczytu, drugi do zapisu i użyć tej konstrukcji z std::tranform

0

Mam taki kod jak go zmodyfikować, żeby zapisywał do pliku, nie dopisywał (app)??

#include<iostream>
#include<algorithm>
#include<conio.h>
#include <fstream>
#include<string>
#include <sstream>

using namespace std;

const char d = 'A' - 'a';

char toUpper(char c)
{
	if ('a' <= c && c <= 'z') return c + d;
	else return c;
}

using namespace std;

int main()
{
	string s;
	fstream plik;
	plik.open("dane.txt", ios::in);
	if (plik.good())
	{
		string napis;

		do
		{
			getline(plik, napis);


			transform(napis.begin(), napis.end(), napis.begin(), ::toupper);
			cout << napis;
			s = napis;
			
			;
			fstream plik("plik.txt", ios::app);
			if (plik.good())
			{

				plik <<s<<endl;

				plik.close();
			}

			plik.close();
		} while (!plik.eof());
		
		
		
		
	}
		
	else cout << "Error! Nie udalo otworzyc sie pliku!" << endl;

	
	
	_getch();
}

Jak daje "out" to mam znów pusty plik, nie wiadomo dlaczego.

PS: A jak dam taki kod:

fstream plik("plik.txt", ios::out);
			if (plik.good())
			{
				string test = "test";
				plik <<s<<endl;
				plik << test;

				plik.close();
			}

To stworzy nowy plik, pierwszej linijki nie zapisze, a tego stringa test już tak, dlaczego?

usunięcie pustego cytatu - @furious programming

1

Edit: Skopiowałem nie ten plik :P Teraz jest ok

#include <iostream>
#include <fstream>
#include <algorithm>

int main()
{
    std::ifstream plik_wej;
    std::ofstream plik_wyj;
    std::string napis;
    
    plik_wej.open("dane.txt", std::ios::in);
    plik_wyj.open("out.txt", std::ios::out);
    if (!plik_wej.good() || !plik_wyj.good())
    {
        std::cout << "Error! Nie udalo otworzyc sie pliku!" << std::endl;
        return 0;
    }
    
    do {
        getline(plik_wej, napis);
        std::transform(napis.begin(), napis.end(), napis.begin(), ::toupper);
        plik_wyj << napis << std::endl;
    } while (!plik_wej.eof());
    plik_wej.close();
    plik_wyj.close();
}

Edit2: to samo, krócej:

#include <iostream>
#include <fstream>
#include <algorithm>

int main()
{
    std::ifstream plik_wej("dane.txt");
    std::ofstream plik_wyj("out.txt");

    if (!plik_wej.good() || !plik_wyj.good()) {
        std::cout << "Error! Nie udalo otworzyc sie pliku!" << std::endl;
        return 0;
    }
    
    std::transform(std::istreambuf_iterator<char>(plik_wej),
                   std::istreambuf_iterator<char>(),
                   std::ostreambuf_iterator<char>(plik_wyj),
                   ::tolower);    
}
2

Wersja absolutnie minimalistyczna:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator> 
#include <cctype>
 
int main()
  {
   using namespace std;
   ifstream fin("dane.txt");
   ofstream fout("out.txt");
   transform(istreambuf_iterator<char>(fin),istreambuf_iterator<char>(),ostreambuf_iterator<char>(fout),::tolower);
   return 0;
  }

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