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

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

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

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

Q&A

解決済

1回答

28542閲覧

文字列の長さを調べるやり方(C++)

2BUT4

総合スコア14

C++

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

0グッド

0クリップ

投稿2017/11/14 15:56

編集2017/11/14 16:00

【参考書】
・やさしいC++

【わからなかったところ】
・文字列の長さの求め方
・NULL文字について

以下に問題文を記述します。

文字列の長さを調べる関数int length(char* str)を作成してください。実際にキーボードから文字列を入力して文字列の長さを調べるコードを記述してください。

【出力される文】

文字列を入力してください。 Hello 文字列の長さは5です。

これに対してわたしが書いてみたコードです。

#include<iostream> #include<cstring> using namespace std; int lenght(char*str){ int a=strlen(str); return a; } int main(){ char str[10]; cout<<"文字列を入力してください。"<<endl; cin>>str; int ans=lenght(str); cout<<"文字列の長さは"<<ans<<"です。"<<endl; }

stlen()関数を使って文字列を求めました。
ただ、参考書の解答は、whileを使って求めていました。
参考書の解答を記載します。

#include<iostream> using namespace std; int lenght(char* str){ int i=0; while(str[i]){    //ここがよくわからないところ i++; } return i; } int main(){ char str[100]; cout<<"文字列を入力してください。"<<endl; cin>>str; int ln=lenght(str); cout<<"文字列の長さは"<<ln<<"です。"<<endl; }

コメントの部分のwhileで行っている処理は、
引数としてもらったchar str[(cin)で入力した文字列]の要素を

(今回の場合はHello)
str[0] H ,str[1] e ,str[2] l ,str[3], l str[4] o ,str[5] '\0'

と確認していって、最後の'\0'(NULL文字)がきたとき、false(つまり0)になるからループを抜けられてi++をされない、i++されたのは、true(整数値をbool型に変換して、0以外の整数)の数という意味なのでしょうか?

現段階で、
・char型の配列の要素であるHなどを数値に置き換えて、判断しているのかわからない
・そもそもNULL文字が==0なのかがわからないし、Hなどの文字が0以外であるかどうかもわからない

ということで、どういう意味かわからなくなってしまいました。
わたしの文章も、わかりにくいかとおもいますが、わかってくれた方は教えていただけると嬉しいです。
よろしくおねがいします!

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

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

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

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

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

guest

回答1

0

ベストアンサー

最後の'\0'(NULL文字)がきたとき、false(つまり0)になるからループを抜けられてi++をされない、i++されたのは、true(整数値をbool型に変換して、0以外の整数)の数という意味なのでしょうか?

かなり回りくどい言い方ですが、おおむね正しい解釈だと思います。

char型の配列の要素であるHなどを数値に置き換えて、判断しているのかわからない

数値に置き換えているのではなく、C/C++でのchar型はもともと整数です。
intよりも狭い範囲の数を表すことができるので、文字を扱う際に主に用いられているだけです。

そもそもNULL文字が==0なのかがわからないし、Hなどの文字が0以外であるかどうかもわからない

ASCIIコードに従います。ASCIIコード表

ついでに

参考書の模範解答について、絶対に従わない方がいい部分が一か所あります。
追記:充分理解した上で使いこなせるなら、この限りではありません。

C++

using namespace std;

名前空間のメリットを完全に潰してしまう一文です。
また、どこまでが標準名前空間の機能であるのかも、不明瞭になってしまいます。

これを用いない場合、coutなどを用いる際にstd::coutと記述する必要があります。
面倒に思えるかもしれませんが、この面倒さが名前の衝突を防いでいると思えば安いものです。


なお、ご覧になっている参考書は、かなりC寄りのC++を扱っています。
無駄にはならないと思いますが、実際のC++のコードを見る際に、違和感があるかもしれません。

ちょっとC++っぽく書いたのがこちら。

C++

1#include <cstdlib> 2#include <string> 3#include <iostream> 4 5size_t length(const std::string& str) { 6 return str.length(); 7} 8 9int main(void) { 10 std::string str; 11 12 std::cout << "文字列を入力してください。" << std::endl; 13 std::cin >> str; 14 std::cout << "文字列の長さは" << length(str) << "です。" << std::endl; 15 16 return 0; 17}

投稿2017/11/14 16:02

編集2017/11/15 02:27
LouiS0616

総合スコア35662

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

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

2BUT4

2017/11/14 18:06

ありがとうございます! char型がもともと整数だということ、ASCIIコードの使い方は(確認したらNULL文字は0でした!)わかりました。 あと返信の内容についてもう少し教えてほしい部分があります。 ・名前空間、というのはLouiS0616さんが書いてくれたコードのように、最初にusing namespace std;と記述しなくても備わっているのでしょうか?名前空間のメリットというものがいまいちわかっていないので、::のような記述が増えることの良さがあまり実感できませんでした。 ・std::のstdとは、なんですか?(今までは参考書のまねをして使っていました) ・return 0;は書いたほうがいいですか? お時間があれば返信していただけるとうれしいです。
LouiS0616

2017/11/14 18:35 編集

名前空間は常に備わっていますし、自分で定義することも出来ます。 関数などを命名する際には、出来るだけわかりやすく簡潔な名前を付けたいものです。 しかし、簡潔な名前を付けると『名前の衝突』(被り)が発生する恐れがあります。 名前空間Aに定義した関数funcと、名前空間Bに定義した同名の関数funcは、 それぞれA::func、B::funcとして区別できます。 開発が大規模になればなるほど、このようなドメイン分けは非常に重要になります。
LouiS0616

2017/11/14 18:28

using namespace A; と宣言すると、A::funcを単にfuncと記述出来て楽チンです。 しかし、同時にusing namespace B; が宣言されると...? コンパイラは、funcがA::funcなのかB::funcなのか判別できません。 この点で、using namespace ....; は、細心の注意を払って用いるべきと言えます。
LouiS0616

2017/11/14 18:31

stdは、スタンダードの略です。 C++に機能として備わっている関数やグローバル変数が存在する名前空間です。 外部のライブラリを用いる場合、異なる名前空間を利用することになります。 名前空間自体は非常に簡単に定義できるので、自分だけのものを作ると愛着が湧くかもしれません。
LouiS0616

2017/11/14 18:34

main関数のreturn 0;のことですよね。これは確か省略可能です(未確認)。 ただし、省略されているコードはあまり見ないです。お行儀が悪く感じます。 回答では簡略化を図るため言及していませんが、私は日頃次のようにしています。 (cstdlibをインクルードしたうえで) return EXIT_SUCCESS; EXIT_SUCCESSの値は結局0なのですが、意味合いはわかりやすくなります。
cateye

2017/11/14 20:06

main()のreturn 0;ですが、これはOSに返す結果です。省略は出来ますが、省略すると何が返るか解りません。UNIX系のOSではそれを元に処理を分岐させたりします。なので省略しない方がいいと思います。int main()と書いていながら返却値がないのは変ですしd^^
episteme

2017/11/14 23:48

C++では「main() が何も返さないとき、return 0; と見なされる」と規格に明記されてるはず。
cateye

2017/11/15 05:02 編集

失礼 ・・・誤解していたようです。 いらぬお手数をかけました。mm [追記] 個人的にはreturnがないのはすごく気持ち悪い(intを返すといっているのにreturnがない)のですが・・・いかがでしょうか?
tacsheaven

2017/11/15 00:18 編集

JIS X3014:2003(C++ のJIS規格書。ISO/IEC 14882:2003の日本語訳)において、3.6.1 の 5 で次のように定義されています。 mainの中のreturn文は、関数mainを抜け出し(その際に自動記憶域期間をもったすべてのオブジェクトを解体し)、その返却値を実引数としてexitを呼び出す働きをもつ。return文に出会うことなく制御が関数mainの終わりに達した場合、次の文の実行と同じ働きをもつ。  return 0;
episteme

2017/11/15 01:16

「using namespace xxx は絶対に使うな」には異論があります。 ヘッダでコレ↑やっちゃうのは名前空間を汚すのでもちろんご法度なのですが、 実装側では(よっぽど広いスコープでなければ)別にいいんちゃう? って思ってます。 これによって名前の衝突が起きたら「ちゃんとコンパイル・エラー」になるんだから。
LouiS0616

2017/11/15 02:26

みなさま、コメントありがとうございます。 私自身はコンパイルエラーより、意味合いが薄れる方に問題がある気がします。 ある程度慣れ、理解したうえでusing namespaceを使うことはありだと思いますが、入門書に『おまじない』で書いてあるのはちょっと... という思いです。
LouiS0616

2017/11/15 02:28

いちおう、回答にもその旨を追記しておきました。 > 追記:充分理解した上で使いこなせるなら、この限りではありません。
2BUT4

2017/11/15 02:46

コメントをくれたみなさま、回答をくれたLouiS0616さん、本当にありがとうございました。 using namespace std;を使う危険性や、なぜ書かれているのかが、みなさまのやりとりからなんとなくわかりました。LouiS0616さんの言われたように、わたしのほうでその意味をもう少し調べ、充分理解できてから使ってみたいと思います。 本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問