質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

1645閲覧

isspace()とispunct()の使い方について

erumoa400

総合スコア14

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/11/07 15:23

toupper()、ispunct()、isspaceを使って回文を判定するプログラムを書こうと思っています。
空白、句読点は無視して大文字小文字も同じものとして扱うという設定です。
文字列の最初と最後の文字を比べて、次は最初+1、最後-1と順番に判定するような処理を考えているのですが、ispanct()とisspaceの使い方が分かりません。
toupper()は文字を大文字に変換するので、大文字小文字の問題を解決できますが、真偽しか返せないispunct()とisspace()を使ってどうすれば残りの空白、句読点を解決できますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

C++

1#include <iostream> 2#include <string> 3#include <algorithm> 4#include <cctype> 5#include <iterator> 6 7int main(){ 8 using namespace std; 9 string str = "No melon, no lemon."; 10 11 str.erase(remove_if(begin(str),end(str),[](char ch) { return isspace(ch) || ispunct(ch); }), 12 end(str)); 13 cout << "空白と句読点を取り除く: [" << str << "]\n"; 14 15 transform(begin(str), end(str), begin(str), [](char ch) { return toupper(ch);}); 16 cout << "大文字に変換: [" << str << "]\n"; 17 18 string rev = str; 19 reverse(begin(rev), end(rev)); 20 cout << "反転: [" << rev << "]\n"; 21 22 cout << "回文か?:[" << ( str == rev ? "yes" : "no" ) << "]\n"; 23 24 return 0; 25}

投稿2021/11/08 05:28

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

erumoa400

2021/11/09 10:29

回答ありがとうございます
guest

0

効率とかをとりあえず度外視すれば,

「入力された文字列からスペースと句読点を取っ払って,残った文字を全部大文字にしたもの」を実際に作ってしまえば簡単であろう.

で,「入力された文字列からスペースと句読点を取っ払って,残った文字を全部大文字にしたもの」をどうやって作るのか? を考える.

結果用の領域を用意して(最初は空っぽにしておき), 入力文字列を先頭側から末尾まで1文字ずつ見ていって, 着目している文字がスペースでも句読点でもないならば, その文字を大文字にしたものを結果用領域の末尾に加える.

とすればよいだろう,とか方針を立てたら,その話を愚直に実装する.

C++

1//スペースと句読点を取っ払い,大文字にした文字列を返す 2std::string Modify( const std::string &Src ) 3{ 4 std::string Result; //結果用の領域を用意して(最初は空っぽにしておき) 5 for( auto i=Src.begin(); i!=Src.end(); ++i ) //入力文字列を先頭側から末尾まで1文字ずつ見ていって 6 { 7 if( !std::isspace( *i ) && !std::ispunct( *i ) ) //着目している文字がスペースでも句読点でもないならば, 8 { Result += std::toupper( *i ); } //その文字を大文字にしたものを結果用領域の末尾に加える. 9 } 10 return Result; 11} 12 13int main(void) 14{ 15 //※入力 16 const std::string InputStr = "No melon, no lemon."; 17 18 //入力を加工した文字列を作る 19 std::string Modified = Modify( InputStr ); 20 //それの逆向きの文字列を作る 21 std::string Reversed = Modified; 22 std::reverse( Reversed.begin(), Reversed.end() ); 23 //両者を比較する 24 std::cout << ( Modified == Reversed ? "Is Palindrome" : "Not Palindrome" ) << std::endl; 25 return 0; 26}

投稿2021/11/08 04:09

fana

総合スコア11708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/11/08 04:18

> 真偽しか返せないispunct()とisspace()を使ってどうすれば残りの空白、句読点を解決できますか? 「これらをどう使うか?」という観点からそもそもの考えを出発しているなら,それは違う. 回答に示した例のように,やるべきことをしっかりと具体的に筋道立てて定めることをすべき. その筋道の中に 「着目している文字がスペースでも句読点でもないならば」という条件が出てきたからこそ 文字がスペースであるか? 文字が句読点であるか? という判定が必要になったわけで, ↓ isspace() はまさに「文字がスペースであるか?」の判定をするのに利用できそうであるから → じゃあ使ってみるか となるのだ.
fana

2021/11/08 04:23

> toupper()、ispunct()、isspaceを使って回文を判定するプログラムを書こうと思っています。 とかいう話の出発点がもう異常. (「思っています」なる文言を素直に受け取った場合)
erumoa400

2021/11/09 10:33

toupper(), ispunct(), isspace()を使って回文判定するプログラムを書くという問題を目にして、今回の質問に至りました。 コメント付きのコード分かりやすくて助かります。 回答ありがとうございます
guest

0

空白、句読点は無視して

と書いているとおり、
isspace()ispunct()が真の時にその文字を無視します。

投稿2021/11/08 03:36

otn

総合スコア84804

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

erumoa400

2021/11/09 10:34

真の時は自動でその文字を無視するんですね。 真偽を返すだけだと勘違いしていました 回答ありがとうございます。
guest

0

ベストアンサー

回文かどうかを判断するとき、スペースや句読点は無視しますよね。
No melon, no lemon. だと NOMELONNOLEMON で回文です。
調べる対象の文字がスペースかどうかを判定するのが isspace、
句読点かどうかを判定するのが ispunct です。

追記

C++

1#include <iostream> // cin, cout, endl 2#include <string> // getline 3#include <cctype> // isspace, ispunct, toupper 4using namespace std; 5 6int main() 7{ 8 string s; 9 getline(cin, s); 10 int i = 0, j = s.size() - 1; 11 while (i < j) 12 if (s[i] はスペースまたは句読点か) i++; 13 else if (s[j] はスペースまたは句読点か) j--; 14 else if (s[i] の大文字と s[j] の大文字は等しいか) i++, j--; 15 else break; 16 cout << (i < j ? "no" : "yes") << endl; 17}

どう書けばいいか分かりますか?

投稿2021/11/07 17:23

編集2021/11/08 03:40
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

erumoa400

2021/11/08 03:34

No melon, no lemonをNOMELONNOLEMONにするために、toupper()でNO MELON, NO LEMONにできますが、そこからisspaceやispunctを使ってNOMELONNOLEMONにする方法が分かっていません。 issapceやispunctが真の時はそれをスキップするような処理が必要なのでしょうか?
erumoa400

2021/11/09 10:37

分かりやすい枠組みのおかげで実装できました。 回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問