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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

4回答

9922閲覧

空白で区切られた数字の演算をするプログラム C言語

azurail0

総合スコア10

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

2グッド

0クリップ

投稿2016/12/19 04:48

編集2016/12/19 04:50

###前提・実現したいこと
C言語の学習をしています。
半角スペース(' ')で区切られた4つの数字を入力し、
入力された数字を演算するプログラムを作りたいと考えています。
入力された文字列をそれぞれint型の配列に格納する方法をご教示いただけないでしょうか?

例 足し算
入力
1 2 34 5
出力
42

###発生している問題・エラーメッセージ

2次元配列に、一文字ずつ格納するところまではできたのですが、 そこからint型に変換することができません。

###該当のソースコード

char strt[100]; char *ptime=strt; i=0; int flag=0; char *strflag[4][10]; fgets(strt, sizeof(strt), stdin); //数字をすべてchar型で読み込みstrflagに一文字ずつ格納していっている。 while(*ptime){ //改行文字削除して文字列の最後にNULLを入れる if(*ptime=='\n'){ *ptime='\0'; }else if(*ptime==' '){ //ひとまとまりの数字を読み込むとflagをインクリメントすることで、flagと数字のまとまりを対応させる strflag[flag][i]='\0'; flag++; printf("\n"); }else{ strflag[flag][i]=*ptime; printf("%c",strflag[flag][i]); i++; } ptime++; }

###試したこと
char *p11;
i=0;

while(strflag[0][i]){ p11=&strflag[0][i]; //格納されているか確認 printf("\n%c",*p11); i++; p11++; } *p11='\0'; p11=p11-i+1; i=0; printf("%s",p11);

このようなコードでまず文字列を表示できるようにしようと思ったのですが、
それすらもできませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
二次元配列を使っていることが原因だとはおもったのですが、自分で調べても、空白をはさんだ文字列を数値化し、それぞれ配列に格納するということができませんでした。

kobaya_c, helmenov👍を押しています

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

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

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

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

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

guest

回答4

0

BAが出たようですが・・・こういう方法もあるという事で

C

1 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <ctype.h> 6 7#define MAX_COL (10) 8 9const char * GetNum(const char *sop, char * dip); 10 11int main() 12{ 13 char buf[1024]; 14 char line[MAX_COL]; 15 int sum= 0; 16 // 17 fputs("Enter 4 numbers ->",stdout); 18 fgets(buf,sizeof buf, stdin); 19 // 20 const char *cptr= buf; 21 while(cptr= GetNum(cptr,line)){ 22 sum+= atoi(line); 23 } 24 printf("sum:%d\n",sum); 25 26 return 0; 27} 28 29const char * GetNum(const char *sop, char * dip) 30{ 31 while(isblank(*sop)){ 32 sop++; 33 } 34 if(*sop== '\n'){ 35 return NULL; 36 } 37 while(isdigit(*sop)){ 38 *dip++= *sop++; 39 } 40 *dip= '\0'; 41 // 42 return sop; 43} 44

エラーチェックはしていません。↓実行結果
Enter 4 numbers ->11 22 33 44
sum:110


Process exited after 7.263 seconds with return value 0

投稿2016/12/19 06:44

編集2016/12/19 13:13
cateye

総合スコア6851

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

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

azurail0

2016/12/19 08:19

ご解答有難うございます。 他のアプローチも教えていただけてとてもうれしいです。 また、isspaceやisdigitなどの便利な関数も知ることができました。 ありがとうございます。 質問なのですが、 for(int i= 0;cptr= GetNum(cptr,line); i++) このfor文の条件式の部分で cptr= GetNum(cptr,line) とあるのですが、この部分がよくわかりません。 基礎の基礎レベルの入門書を読み終えたばかりで、そのような例を見たことがなく 検索ワード等もわかりません。。。 お時間あるときに、解説していただけるとうれしいです。 よろしくお願いいたします。
cateye

2016/12/19 11:34 編集

GetNum()を見ればわかるかと思いますが、最初に空白をスキップして数字をlineに取り出しています。そして、取り出した数字の後ろを指すポインタを返しているわけです。それを繰り返せば、数字の部分だけ取り出すことができます。最初に改行('\n')を判定しているのはfgets()が改行まで文字列として取り込むためです。従って、改行が来たら文字列をすべて取り出し終わったと判断してNULLを返すことでfor()ループを抜けるわけです。iは使っていないので、while(cptr= GetNum(cptr,line))でもよかったかと今思っていますw・・・ちなみにNULLポインタは偽(=0)と判断されます
cateye

2016/12/19 13:16

修正してみました。また、数字の後に空白があっても動作するようにisspace()をisblank()に変えてあります。
azurail0

2016/12/20 06:30

丁寧にご回答していただき、ありがとうございますm(_ _)m forの条件式にNULLポインタを使っていたのを初めて見たので、少し混乱してよくわからなくなっていましたw *dip++= *sop++; この形も初めてみたので、cateye様のおかげで、ポインタに対する理解と関数に関する知識も深まりました! fgets()のことなども丁寧に教えてくださり、本当にありがとうございました。
guest

0

ベストアンサー

例えは、こんな感じ

c

1#include<stdio.h> 2void main(){ 3 char strt[100]; 4 char *ptime=strt; 5 int i=0; 6 int ttl=0; 7 int flag=0; 8 char strflag[4][10] = {0}; 9 fgets(strt, sizeof(strt), stdin); 10 //数字をすべてchar型で読み込みstrflagに一文字ずつ格納していっている。 11 while(*ptime){ 12 //改行文字削除して文字列の最後にNULLを入れる 13 if(*ptime=='\n'){ 14 *ptime='\0'; 15 }else if(*ptime==' '){ //ひとまとまりの数字を読み込むとflagをインクリメントすることで、flagと数字のまとまりを対応させる 16 //strflag[flag][i]='\0'; 17 flag++; 18 printf("\n"); 19 i=0; 20 ptime++; 21 }else{ 22 strflag[flag][i]=*ptime; 23 printf("%c ",strflag[flag][i]); 24 i++; 25 ptime++; 26 } 27 } 28 printf("\n"); 29 for (i=0; i<4; i++){ 30 ttl+=atoi(&strflag[i]); 31 } 32 printf("TTL:%d\n",ttl); 33}

たぶんご存知でしょうが、王道のscanf

c

1#include <stdio.h> 2void main(void)3{4 int n[4];5 int *p;6 p=n;7 scanf("%d%d%d%d",p,p+1,p+2,p+3);8 printf("%d %d %d %d\n", *p,*(p+1),*(p+2),*(p+3));9 printf("ttl:%d\n",*p + *(p+1) + *(p+2) + *(p+3));10}11

投稿2016/12/19 05:55

編集2016/12/19 15:31
A.Ichi

総合スコア4070

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

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

azurail0

2016/12/19 06:35

ご解答有難うございます。 strflag[4][10]をポインタで宣言していたことと *ptime==' 'のところでiに0を代入するのが抜けていたため おかしな動作になっていたみたいですね。 A.Ichi様のおかげで解決しました。 本当にありがとうございました。
azurail0

2016/12/21 06:46

scanfが空白で区切られた数字をそのように読み取ることができるのははじめて知りました、、、。 scanfに対する理解が浅かったようなので調べてみると 「制御文字列以外の文字に遭遇するまで文字を読み取り、その文字を破棄する」機能があるみたいですね。(参考URL:http://wisdom.sakura.ne.jp/programming/c/c58.html) 追記していただき、ありがとうございました。
guest

0

根本的解決ではないですが。 ( 質問にあるコードは使わないので。 )

それでもいいなら。

私なら、

  1. まず文字列としてユーザ入力を受け付ける。 -> char strt[] に格納
  2. 受け取ったデータを strtok関数を使って 文字列として分割 -> char strNum[] に格納
  3. 2で取得したデータを atoi関数を使って int型に変換していく -> int num[] に格納
  4. 3で取得した int num[] を使って計算 & 出力等

ですかね。

文字列として取得 -> 取得した文字列データを strtok関数で"文字列として" 分割 -> atoi関数で int型に変換

っていう感じにします。

投稿2016/12/19 04:55

BeatStar

総合スコア4958

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

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

azurail0

2016/12/19 06:33

解答ありがとうございます。 自分ではこの方法しか思いつかなかったので、とても参考になりました。 strtok関数をつかったBestStar様の方法でもプログラムを組んでみようと思います。 ありがとうございました。
azurail0

2016/12/19 07:16

#include <stdio.h> #include <string.h> int main(void){ // Here your code ! char str[100]; char *p=str; int kazu[4]; gets(str); //printf("%s",str); //printf("%s",p); p=strtok(str," "); kazu[0]=atoi(p); printf("%d",kazu[0]); int i=1; while(p!=NULL){ p=strtok(NULL," "); if(p!=NULL){ kazu[i]=atoi(p); i++; } } int sum=0; for(int j=0;j<i;j++){ sum+=kazu[j]; } printf("\n%d",sum); } 足し算するプログラムを作ってみたのですが、 strtok関数にさえ慣れてしまえば、かなり簡単に作れるように感じました。 便利な関数を教えてくださり、ありがとうございました。m(._.)m
BeatStar

2018/12/23 01:46

strok関数は内部でstaticな変数を用いているようなのでなんか癖が強いですが、私は大体これでやっていますので。
guest

0

必ずポインタや二次配列を使うとかのせい減がないとしたら、これで必要十分な量になるでしょう。

C言語

1#include<stdio.h> 2 3int main(void) 4{ 5 int nu[4], i; 6 7 printf("Num 1 2 3 and4 ?=>"); 8 scanf("%d%d%d%d", &nu[0], &nu[1], &nu[2], &nu[3]); 9 10 for(i=1 ; i<4; i++) 11 { 12 nu[0] += nu[i]; 13 } 14 15 printf("Sum == %d", nu[0]); 16 17 return 0; 18}

投稿2018/12/22 07:01

ZhenZeZhang

総合スコア33

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問