ページ 11

デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 09:15
by ティキタカ
今カエサル暗号を作っています。
エラーが出るのですが、どこがうまく行ってないのかわかりません。
条件はclassを使って,ひとつはprivate member data stringをプリントするためで。
後はデコードとエンコードのためのpublicなのですが、条件ともかなり違うような気がします
C++をはじめてまだ日が浅いです、よろしくお願いします。

コード:

#include <iostream>
#include <string>
using namespace std;
class Caesar
{
public:
    void Encode();
    void Decode();
};
void Caesar::Encode()
{
    string input;
    int count=0, length;
    cout<<"Please enter a string that you would like to encode"<<endl;
    getline(cin, input);
    length =(int) input.length();
    int shiftnumber;
    cout<<"please enter what integer cipher shift key you use?"<<endl;
    cin>>shiftnumber;
    for (count=0; count< length; count++)
    {
       if (isalpha (input [count]))
       {
           input[count]=tolower(input[count]);
           for (int i=0; i<shiftnumber; i++)
           {
               if(input [count]=='z')
                  input [count]='a';
               else
                   input[count]++;
           }
    
       }
    }
        cout<<"The answer is "<<input<<endl;
}
void Caesar::Decode()
{
    string input;
    int count=0, length;
    cout<<"Please enter a string that you would like to encode"<<endl;
    getline(cin, input);
    length =(int) input.length();
    int shiftnumber;
    cout<<"please enter what integer cipher shift key you use?"<<endl;
    cin>>shiftnumber;
    for (count=0; count< length; count++)
    {
        if (isalpha (input [count]))
        {
            input[count]=tolower(input[count]);
            for (int i=0; i<shiftnumber; i++)
            {
                if(input [count]=='a')
                    input [count]='z';
                else
                    input[count]--;
            }
            
        }
    }
    cout<<"The answer is "<<input<<endl;
}




    
int mian()
{   Caesar PLayer;
    cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
    string sentaku, mouika;
    cout<<"Would you like to encode? please enter 'E'"<<endl;
    cout<<"Would you like to decode? please enter 'D'"<<endl;
    cout<<"or Quit please enter 'Q'"<<endl;
    cin>>sentaku;
    while(true)
    {
         if (sentaku=="E")
         {PLayer.Encode();}
         if (sentaku=="D")
         {PLayer.Decode();}
         if (sentaku=="Q")
         {break;}
         else
         {continue;}
    }
    cout<<"Would you like to encode? please enter 'E'"<<endl;
    cout<<"Would you like to decode? please enter 'D'"<<endl;
    cout<<"or Quit please enter 'Q'"<<endl;
    cin>>mouika;

    return 0;
}

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 10:54
by ティキタカ
もうひとつお願いします
これだと、大文字のアルファベットも小文字になってしまうのですが、大文字は大文字、小文字は小文字にするためにはどうすれば良いですか?

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 11:22
by みけCAT
ティキタカ さんが書きました:今カエサル暗号を作っています。
エラーが出るのですが、どこがうまく行ってないのかわかりません。
main関数が見当たりません。また、mian関数において、最初にQ以外を入力すると無限ループになります。
ティキタカ さんが書きました:これだと、大文字のアルファベットも小文字になってしまうのですが、大文字は大文字、小文字は小文字にするためにはどうすれば良いですか?
まず強制的に小文字にするのをやめて、大文字に対応する処理を追加すれば良いです。

main関数を追加し、無限ループになりにくくして、大文字に対応し、選択後の改行の読み飛ばしを追加したコードです。

コード:

#include <iostream>
#include <string>
using namespace std;

void ignoreLine()
{
    string dummy;
    getline(cin, dummy);
}

class Caesar
{
public:
    void Encode();
    void Decode();
};
void Caesar::Encode()
{
    string input;
    int count=0, length;
    cout<<"Please enter a string that you would like to encode"<<endl;
    getline(cin, input);
    length =(int) input.length();
    int shiftnumber;
    cout<<"please enter what integer cipher shift key you use?"<<endl;
    cin>>shiftnumber;
    ignoreLine();
    for (count=0; count< length; count++)
    {
       if (isalpha (input [count]))
       {
           for (int i=0; i<shiftnumber; i++)
           {
               if(input [count]=='z')
                   input [count]='a';
               else if(input [count]=='Z')
                   input [count]='A';
               else
                   input[count]++;
           }
       }
    }
        cout<<"The answer is "<<input<<endl;
}
void Caesar::Decode()
{
    string input;
    int count=0, length;
    cout<<"Please enter a string that you would like to encode"<<endl;
    getline(cin, input);
    length =(int) input.length();
    int shiftnumber;
    cout<<"please enter what integer cipher shift key you use?"<<endl;
    cin>>shiftnumber;
    ignoreLine();
    for (count=0; count< length; count++)
    {
        if (isalpha (input [count]))
        {
            for (int i=0; i<shiftnumber; i++)
            {
                if(input [count]=='a')
                    input [count]='z';
                else if(input [count]=='A')
                    input [count]='Z';
                else
                    input[count]--;
            }
        }
    }
    cout<<"The answer is "<<input<<endl;
}



int mian()
{   Caesar PLayer;
    cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
    string sentaku;
    while(true)
    {
        cout<<"Would you like to encode? please enter 'E'"<<endl;
        cout<<"Would you like to decode? please enter 'D'"<<endl;
        cout<<"or Quit please enter 'Q'"<<endl;
        cin>>sentaku;
        ignoreLine();
        if (sentaku=="E")
        {PLayer.Encode();}
        if (sentaku=="D")
        {PLayer.Decode();}
        if (sentaku=="Q")
        {break;}
        else
        {continue;}
    }

    return 0;
}

int main()
{
    return mian();
}
ティキタカ さんが書きました:条件はclassを使って,ひとつはprivate member data stringをプリントするためで。
後はデコードとエンコードのためのpublicなのですが、条件ともかなり違うような気がします
このコードに、前のコードのEncode関数とDecode関数の、inputの宣言と入力処理を外したものを追加し、呼び出し処理を追加するといいかもしれません。
(解釈が間違っているかもしれませんが)

コード:

#include <iostream>
#include <string>
using namespace std;

void ignoreLine()
{
    string dummy;
    getline(cin, dummy);
}

class Caesar
{
private:
    string input;
public:
    void Input();
    void Print() const;
};

void Caesar::Input()
{
    cout<<"Please enter a string that you would like to deal with"<<endl;
    getline(cin, input);
}

void Caesar::Print() const {
    cout<<input<<endl;
}

int mian()
{   Caesar PLayer;
    string sentaku;
    while(true)
    {
        cout<<"Would you like to set string? please enter 'S'"<<endl;
        cout<<"Would you like to print string? please enter 'P'"<<endl;
        cout<<"or Quit please enter 'Q'"<<endl;
        cin>>sentaku;
        ignoreLine();
        if (sentaku=="S")
        {PLayer.Input();}
        if (sentaku=="P")
        {PLayer.Print();}
        if (sentaku=="Q")
        {break;}
        else
        {continue;}
    }

    return 0;
}

int main()
{
    return mian();
}

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 12:36
by ティキタカ
返信ありがとうございます。
試してみます!
ちなみに今時間があったので自分なりに頑張ってみて、いろいろかえてしまったのですが(ほとんど変わったのはdecodeとencode のisalphaを「使用したところです)、空白などをメッセージの間に作ってしまうとコードがおかしくなります(例えばyou areというように)
この場合はどうすれば良いですか?
したのコードです、お願いします。

コード:

#include <iostream>
#include <string>
using namespace std;
class Caesar//caesar code
{
private:
    string message;
    int cipher;
public:
    void Encode();
    void Decode();
};
void Caesar::Encode()//encoding
{
    cout<<"Please enter a string that you would like to encode"<<endl;
    cin>>message;
    cout<<"Please enter what integer cipher shift key you use?"<<endl;
    cin>>cipher;
    cout<<"This is your message ";
    for (int count=0; count<message.length(); count++)
        {
         if(message.at (count)<='z' && message.at(count)>='a')
           {
               cout<<(char)(message.at(count)+cipher);
           }
         else if (message.at(count)<='Z' && message.at(count)>='A')
           {
               cout<<(char)(message.at(count)+cipher);
           }
        }
    cout<<endl;
    
}
void Caesar::Decode()//decoding
{
    cout<<"Please enter a string that you would like to Decode"<<endl;
    cin>>message;
    cout<<"Please enter what integer cipher shift key you use?"<<endl;
    cin>>cipher;
    cout<<"This is your message ";
    for (int count=0; count<message.length(); count++)
        {
           {
           if (message.at(count)>='a' && message.at(count)<='z')
              {
                cout<<(char)(message.at(count)-cipher);
              }
           else if (message.at(count)>='A' && message.at(count)<='Z')
              {
                cout<<(char)(message.at(count)-cipher);
              }
           }
        }
    cout<<endl;
}

int main()
{   Caesar PLayer;
    string sentaku;
    cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
    cout<<"Would you like to encode? please enter 'E'"<<endl;
    cout<<"Would you like to decode? please enter 'D'"<<endl;
    cout<<"or Quit please enter 'Q'"<<endl;
    cin>>sentaku;
    while(true)//choice
    {
        if (sentaku=="E")
        {PLayer.Encode();}
        else if (sentaku=="D")
        {PLayer.Decode();}
        else if (sentaku=="Q")
        {break;}
        cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
        cout<<"Would you like to encode? please enter 'E'"<<endl;
        cout<<"Would you like to decode? please enter 'D'"<<endl;
        cout<<"or Quit please enter 'Q'"<<endl;
        cin>>sentaku;
    }
    return 0;
}

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 12:44
by みけCAT
ティキタカ さんが書きました:ちなみに今時間があったので自分なりに頑張ってみて、いろいろかえてしまったのですが(ほとんど変わったのはdecodeとencode のisalphaを「使用したところです)、空白などをメッセージの間に作ってしまうとコードがおかしくなります(例えばyou areというように)
この場合はどうすれば良いですか?
「おかしくなります」というのは、具体的にどのような出力を期待していて、実行するとどうなってしまうのですか?

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 13:08
by ティキタカ
説明不足でした。すみません。
例えばABCDやIamaboyのように隙間を空けずに文字を入力したものはちゃんとencode、decodeされるのですが、例えばA B C DやI am a boyいうふうに少しでも文字と文字、または言葉と言葉の間をあけるとエラーがおきて、無限ループのような症状が出ます、これを改善するためにはどうしたら良いでしょうか。
IamaboyでもI am a boy でもどちらでもきちんと出力されるようにしたいのです。

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 13:20
by みけCAT
改善方法は後で考えます。

例えば、
string: It's_a_zombie.
key: 1
でEncodeした時の出力はどうなってほしいですか?

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 13:27
by ティキタカ
Ju't_b_apncjf
こんな感じでお願いします。

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 16:52
by みけCAT
>>演算子を使うと改行文字が読み込めなかったため、std::getlineを使いたくないのであればstd::cin.get()を使えば良さそうです。
また、アルファベットでもピリオドでもない文字を出力する処理を追加し、シフトはアルファベットの範囲で回るようにしました。

コード:

#include <iostream>
#include <string>
using namespace std;

void GetData(string& s)
{
    s="";
    while (!cin.eof())
        {
          char c;
          //cin>>c;
          cin.get(c);
          if (c=='\r' || c=='\n')
          {break;}
          s+=c;
        }
}

void GetData(int& i)
{
    string d;
    GetData(d);
    int sign=1;
    i=0;
    for (size_t count=0; count<d.length(); count++)
        {
          if(d.at (count)<='9' && d.at(count)>='0')
            {
              i=i*10+d.at(count)-'0';
            }
          else if (d.at (count)=='-' && count==0)
            {
              sign=-1;
            }
        }
    i*=sign;
}

class Caesar//caesar code
{
private:
    string message;
    int cipher;
public:
    void Encode();
    void Decode();
};
void Caesar::Encode()//encoding
{
    cout<<"Please enter a string that you would like to encode"<<endl;
    GetData(message);
    cout<<"Please enter what integer cipher shift key you use?"<<endl;
    GetData(cipher);
    cout<<"This is your message ";
    for (size_t count=0; count<message.length(); count++)
        {
          if(message.at (count)<='z' && message.at(count)>='a')
            {
                cout<<(char)('a'+((message.at(count)-'a'+cipher)%26+26)%26);
            }
          else if (message.at(count)<='Z' && message.at(count)>='A')
            {
                cout<<(char)('A'+((message.at(count)-'A'+cipher)%26+26)%26);
            }
          else if (message.at (count)!='.')
            {
                cout<<(char)message.at(count);
            }
        }
    cout<<endl;
    
}
void Caesar::Decode()//decoding
{
    cout<<"Please enter a string that you would like to Decode"<<endl;
    GetData(message);
    cout<<"Please enter what integer cipher shift key you use?"<<endl;
    GetData(cipher);
    cout<<"This is your message ";
    for (size_t count=0; count<message.length(); count++)
        {
          {
          if (message.at(count)>='a' && message.at(count)<='z')
            {
              cout<<(char)('a'+((message.at(count)-'a'-cipher)%26+26)%26);
            }
          else if (message.at(count)>='A' && message.at(count)<='Z')
            {
              cout<<(char)('A'+((message.at(count)-'A'-cipher)%26+26)%26);
            }
          else if (message.at (count)!='.')
            {
                cout<<(char)message.at(count);
            }
          }
        }
    cout<<endl;
}

int main()
{   Caesar PLayer;
    string sentaku;
    cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
    cout<<"Would you like to encode? please enter 'E'"<<endl;
    cout<<"Would you like to decode? please enter 'D'"<<endl;
    cout<<"or Quit please enter 'Q'"<<endl;
    GetData(sentaku);
    while(true)//choice
    {
        if (sentaku=="E")
        {PLayer.Encode();}
        else if (sentaku=="D")
        {PLayer.Decode();}
        else if (sentaku=="Q")
        {break;}
        cout<<"Welcome to the Caesar Encoder/Decoder!"<<endl;
        cout<<"Would you like to encode? please enter 'E'"<<endl;
        cout<<"Would you like to decode? please enter 'D'"<<endl;
        cout<<"or Quit please enter 'Q'"<<endl;
        GetData(sentaku);
    }
    return 0;
}

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月16日(土) 17:38
by ティキタカ
ありがとうございます、自分でもずっと考えていたのですが、これで解決する事が出来ました。

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月17日(日) 17:41
by ISLe()
余計なことかもしれませんが、
言語仕様上はアルファベットの文字コードが連続している保証がないので
環境を明記していただくのが良いかと思います。

Re: デバックと条件とあってないと思うので、教えてください

Posted: 2015年5月19日(火) 10:13
by ティキタカ
コメントありがとうございます
初心者なので、何事も勉強になります