Nowe posty

Autor Wątek: Zapisywanie dziwnego pliku  (Przeczytany 1074 razy)

Offline bolexpl

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 5
    • Zobacz profil
Zapisywanie dziwnego pliku
« dnia: 2016-05-18, 20:23:30 »
Witam!
Według zadań maturalnych napisałem taki program do szyfru cezara.
#include <iostream>
#include <fstream>

using namespace std;

//tutaj zamieniam znak
char zamien(char znak,int k){
    char alf[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    int z;

    for(int i=0; i<26; i++){
        if(znak == alf[i]){
            z=(i+k)%26;
            return alf[z];
        }
    }
}

//szyfruję cały wyraz
string szyfr(string x, int k){
    string wynik="";
    for(int i=0; i<x.size();i++){
        wynik+=zamien(x[i],k);
    }
    return wynik;
}

int main(){
    fstream plik;
    plik.open("dane_6_1.txt",ios::in); //pobieram dane do zaszyfrowania

    fstream wynik;
    wynik.open("wynik.txt",ios::out);

    string linia;
    while(getline(plik,linia)){
        wynik << szyfr(linia,107)<<endl;
    }
}

Zapisuję wynik do pliku wynik.txt. Kiedy próbuję wyświetlić przez nano, vim, cat to jest normalnie.
Windowsowy notatnik też sobie radzi.
Jednak Gedit pokazuje krzaki:


Kiedy skompiluję i wykonam to na windowsie to jest normalny i działający plik.
Dziwny plik tworzy się tylko na Ubuntu 12.04.
Próbowałem jeszcze na Windowsie, Kali i Ubuntu 15.04 i wszędzie tworzy się normalny plik.

Wie może ktoś w czym problem?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 2538
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
    • keybase.io/pkraszewski
Odp: Zapisywanie dziwnego pliku
« Odpowiedź #1 dnia: 2016-05-18, 20:43:11 »
W niczym nie ma problemu. Gedit z jakiegoś powodu traktuje ten plik jako zapisany w UTF16 i dlatego wyświetla "krzaki".

BTW, nie słyszałem o szyfrze Cezara z k większym od 26... A wyszukiwanie liniowe znaku do zaszyfrowania to w ogóle majstersztyk optymalizacji.

Bez kontroli błędów (zakładamy, że w tekście są tylko duże litery)
char zamien(char znak,int k){
 return 'A'+((znak-'A'+k)%26);
}

Znaki spoza alfabetu a-z A-Z zwracane są "na wprost"
char zamien(char znak,int k){
 if(znak>='A' && znak<='Z') return 'A'+((znak-'A'+k)%26);
 if(znak>='a' && znak<='a') return 'a'+((znak-'a'+k)%26);
 return znak
}
Paweł Kraszewski
~Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

Offline bolexpl

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 5
    • Zobacz profil
Odp: Zapisywanie dziwnego pliku
« Odpowiedź #2 dnia: 2016-05-18, 22:17:37 »
Taki klucz jest w zadaniach maturalnych.
A w pliku są tylko duże litery łacińskie.

A co do twojego kodu możesz wyjaśnić w jaki sposób działa ta część?
'A'+((znak-'A'+k)%26)
Dopiero zaczynam naukę programowania.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 2538
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
    • keybase.io/pkraszewski
Odp: Zapisywanie dziwnego pliku
« Odpowiedź #3 dnia: 2016-05-18, 22:36:08 »
W krokach:
char zamien(char znak,int k){
  /* 'A' to kod ASCII litery A */

  /* Zamienia zakres 'A'-'Z' na 0..25, bo od kodu litery odejmuje kod 'A' */
  char numer_znaku = znak-'A';

  /* Dodaje klucz. Zakres jest od k do k+25 */
  char zakodowany_numer_znaku = numer_znaku+k; 

  /* Sprowadza zakres z powrotem do 0..25 operacją modulo */
  zakodowany_numer_znaku = zakodowany_numer_znaku%26;

  /* Dodaje do wyniku 0..25 kod znaku 'A', sprowadzając go z powrotem do zakresu 'A'-'Z' */
  char zakodowany_znak = 'A'+zakodowany_numer_znaku;

  return zakodowany_znak;
}
Paweł Kraszewski
~Gentoo/FreeBSD/OpenBSD/Specjalizowane customy