0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【C++】constを使用・C言語スタイルの文字列をポインタとして取得

Last updated at Posted at 2022-11-08

5個の数値を入力し、それぞれに「0が含まれていれば10で割り、5が含まれていれば5で割る」作業を行い (int型・小数部分は切り捨てる) 、それらの合計を求めて出力表示するプログラムを作ります。例えば

15 34
66 77
51 83
70 11
149 38

上のように入力すると
(判定する数, 割られる数)=(15, 34)(66, 77)(51, 83)(70, 11)(149, 38)
とペア分けされ、それぞれのペアの割られる数の方を指定された数で割って (割らない場合もある) 足し合わせるので、6 + 77 + 16 + 1 + 38 より 138 が出力されるはずです。

まずは次のようにプログラムを作りました。

間違ったプログラム
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main(){
	
	int date[100], part[100];
	for(int i = 0; i < 5; i++){
		cin >> date[i];
		cin >> part[i];
	}
	
	int j = 0, sum = 0;
	while(j < 5){
		string buffer = to_string(date[j]);
		char* str = buffer.c_str();
		char* p_0 = strchr(str,'0');
		char* p_5 = strchr(str,'5');
		if(p_0 != NULL){
			part[j] /= 10;
			sum += part[j];
		}else if(p_5 != NULL){
			part[j] /= 5;
			sum += part[j];
		}else{
			sum += part[j];
		}
		j++;
	}
	cout << sum << endl;
	
}

出てきた数値が違うといった問題でなく、そもそもコンパイルが出来ませんでした。エディタではwhile文内のchar* str = buffer;の部分にエラーが出ていました。

エラー箇所の修正

(C++) _ ブラウザでプログラミング・実行ができる「オンライン実行環境」_ paiza.IO および他 10 ページ - 個人 - Microsoft​ Edge 2022_11_08 9_14_06.png
要するに、std::stringからchar*への変換が出来ないらしい。

charはC言語形式なので、C++ → C に対応する型変換が必要になります。
参考:

着目したのは、constを使用した変換「std::string → const char*」です。この方法はC言語スタイルの文字列をポインタとして取得するのに使うらしいです。
strchrはC言語の文字列でお馴染みのchar型にしか扱えない (と思っている) ので、今回のようなケースにピッタリかもしれないと、上の変換方法を選択しました。

ただ、「std::string → const char*」が何故「C言語形式の文字列へ変換」になるのか、イマイチよく分かりません。
単純に「関数でのポインタ引数に対する書き換えから保護する」ならまだ分かります。しかし………………
変数の値を変更せず定数として宣言する際に使う修飾子としての役割を持つconstの事を考えると、「なぜ今constなのか?ここでのconstはどう働きかけているのか?」となおさら疑問に感じてしまいます。

上のサイトをお手本にさせて頂くと、こんな感じでしょうか。自分のプログラムでconstを使ったのは、今回が初めてです。

		string buffer = to_string(date[j]);
		const char* str = buffer.c_str();
		const char* p_0 = strchr(str,'0');
		const char* p_5 = strchr(str,'5');

初期化時の変数の値を書き換え禁止 (読み取り専用) にする事で知られる「const」。僕の場合、constは「渡された構造体の内容を変更しないという事を明示するために指定するもの」として初めて知る事になりました。

ただ、前にも述べた通り、僕はconstに対しての理解が未だ浅いため、あまり表に出ない隠れた役目は何なのか悩んでいます。

参考:

ひとまず、プログラムを仕上げます。

完成プログラム
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main(){
	
	int date[100], part[100];   //date:調査する数値 (配列) , part:同じ要素番目のdateに対応する”割られる数”(配列)
	for(int i = 0; i < 5; i++){
		cin >> date[i];
		cin >> part[i];
	}
	
	int j = 0, sum = 0;
	while(j < 5){
		string buffer = to_string(date[j]);
		const char* str = buffer.c_str();
		const char* p_0 = strchr(str,'0');
		const char* p_5 = strchr(str,'5');
		if(p_0 != NULL){
			part[j] /= 10;
			sum += part[j];
		}else if(p_5 != NULL){
			part[j] /= 5;
			sum += part[j];
		}else{
			sum += part[j];
		}
		j++;
	}
	cout << sum << endl;
	
}

僕の期待通りに動きました。出力画面では 138 のみを表示させている状態です。

まとめ

今回僕にとって大きかったのは、constに触った事です。今まで簡単なプログラムしか書いていなく、「関数や変数の型が複雑になる」とconstを厄介払いしてきたので、今回こうして使わざるを得ない状況に立たされて、仕組みを理解出来るよう調べているところです。
プログラムの方は問題なさそうなので、constについてまた新しい発見をしたら記事を更新します。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?