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

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

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

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

Q&A

解決済

3回答

1995閲覧

文字列で表された数値の足し算

Savanof

総合スコア33

C

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

0グッド

0クリップ

投稿2021/05/30 10:22

編集2021/05/30 10:38

前提・実現したいこと

C言語で、キーボードから二つの数を入力し、その二つの数を基に足し算を行うプログラムの作成を行いたいと思っています。

該当のソースコード

ソースコードの要件で、longint構造体と、longint_add関数を変更(引数を書き変えるなど)する事ができません。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <stdint.h> 4#include <string.h> 5#include <strings.h> 6 7#define MAX_INPUT 100 8 9struct longint { 10 char *val; // 文字列型 11}; 12 13 14void longint_add(struct longint *p, struct longint *q, struct longint *r){ 15 16 // 埋められない場所 17 18 19 } 20 21 22int main(){ 23 24 struct longint Number1 , Number2 , Add_Answer1 , Add_Answer2; 25 26 struct longint *pNumber1 = &Number1; 27 struct longint *pNumber2 = &Number2; 28 struct longint *pAdd_Answer1 = &Add_Answer1; 29 struct longint *pAdd_Answer2 = &Add_Answer2; 30 31 char input1[MAX_INPUT]; 32 char input2[MAX_INPUT]; 33 34 35 printf("Enter The First LongInt"); 36 fgets(input1 , MAX_INPUT , stdin); 37 pNumber1 -> val = input1; 38 39 40 printf("Enter The Second LongInt"); 41 fgets(input2 , MAX_INPUT , stdin); 42 pNumber2 -> val = input2; 43 44 longint_add(pNumber1 , pNumber2 , pAdd_Answer1); 45 46 47}

発生している問題/やりたい事

やりたい事としては、下のような形なのですが、4番と5番が実装できません。

  1. main関数内でキーボードからの二つの入力を受け取る(できている)
  2. 受け取った入力をlongint構造体に入れる(できている)
  3. Int_add関数が定める形で、引数を渡す(できている)
  4. Int_Add関数の要件上、ポインタを渡す事になっているため、ポインタの指す値を入手する(できていない)
  5. Int_Add関数の中で引数をint型やfloat型などに変更して、足し算を行う。(できていない)

お忙しいとは思いますが、よろしくお願いいたします。
情報に不足がありましたら、ご指摘お願いいたします。

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

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

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

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

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

guest

回答3

0

1234567789を筆算で足すときに、どういうやり方をしているか思い出して、
それと同じやり方をすればいいです。
#追記
筆算のやり方が分からないと言うことなので。

C

1int add(char p, char q, int carry, char *r){ 2 int ans; 3 ans = (p - '0') + (q - '0') + carry; 4 *r = ans % 10 + '0'; 5 return ans/10; 6} 7 8void longint_add(struct longint *p, struct longint *q, struct longint *r){ 9 char *p0, *p1, *q0, *q1; 10 int pe=0, qe=0; // 全部の桁が終わったかフラグ 11 char ans[MAX_INPUT+1], *ans1; 12 int carry=0; // 繰り上がり 13 14 ans[MAX_INPUT] = '\0'; 15 ans1 = ans + MAX_INPUT - 1; 16 p0 = p->val; 17 for(p1=p0; *(p1+1)>='0'; p1++); // p1 を最下桁にセット 18 q0 = q->val; 19 for(q1=q0; *(q1+1)>='0'; q1++); // q1 を最下桁にセット 20 while(!pe && !qe){ // 両方とも全部の桁が終わるまでループ 21 carry = add( pe ? '0' : *p1, qe ? '0' : *q1, carry, ans1); 22 if(p0==p1) { // 全部の桁が終わったか? 23 pe = 1; 24 }else{ 25 p1--; 26 } 27 if(q0==q1){ // 全部の桁が終わったか? 28 qe = 1; 29 }else{ 30 q1--; 31 } 32 ans1--; 33 } 34 if(carry){ 35 *ans1 = carry + '0'; 36 }else{ 37 ans1++; 38 } 39 strcpy(r->val, ans1); 40}

あと、呼び出し前に、

C

1char answer[MAX_INPUT+1]; 2~~ 3pAdd_Answer1 -> val = answer;

のような、答えの格納エリアの用意が必要です。

投稿2021/05/30 10:32

編集2021/05/30 13:55
otn

総合スコア85901

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

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

otn

2021/05/30 10:33

タイトルが質問内容を表してないので、 「文字列で表された数値の足し算」 がいいでしょう。書き換えましょう。
Savanof

2021/05/30 10:36

回答ありがとうございます。そのような数を筆算する時は繰り上げ等々して筆算を行うと思うのですが、"それと同じやりかた"というのが良く分らないです。 ポインタ構造体を仮に足し算を行っても、メモリ上の番地の足し算で実際の数値計算の結果にはならないと思うのですが、どういう意味がもう少し詳しく教えて頂けるとありがたいです。
Savanof

2021/05/30 10:40

タイトルを書き直しました。質問の意図としては 「ポインタ構造体を実際の値(入力した値)に戻すにはどうしたらいいか」という事でした。文字列型に戻せればatoi等々で多分変換できると思っています。
episteme

2021/05/30 11:07

「(atoiで変換できないほどに)大きい桁数の整数を足せ」って題意ではないのかしら。
Savanof

2021/05/30 11:25

実際の要件としては、そのような形なのでatol,long型で変換をかけようと思っていました。
otn

2021/05/30 13:13

最大99桁なので、atolとか全く無理です。 1桁ずつ筆算しましょう。
Savanof

2021/05/30 13:15

otnさん , epistemeさん すいません、元々Pythonを書いていたので多倍長整数の感覚が全然なく、一番大きいタイプのatolであれば対応できるだろうと思い込んでいました。多倍長整数の計算が必要になると思うので、そうします。 ありがとうございます。
otn

2021/05/30 13:58

追記しました。 > 一番大きいタイプのatolであれば対応できるだろうと思い込んでいました。 なんと!
Savanof

2021/05/31 06:36

回答ありがとうございます。otnさんのコードを基に自分で筆算するコードを書いてみようと思います。
guest

0

ベストアンサー

文字列と数値の相互変換がすでに出来ているのなら、下記のようにすればよいかと思います。

c++

1void longint_add(struct longint *p, struct longint *q, struct longint *r){ 2 3 long int a=mystoi(p->val); 4 long int b=mystoi(q->val); 5 6 myitos(r->val,a+b); 7 } 8long int mystoi(const char*); // 文字列を数値に変換 9void myitos(char*,long int); // 数値を文字列に変換

Add_Answer1のvalの領域確保の初期化が抜けている?みたいなので、このまま計算結果を書き込むと動作が不定になるので注意が必要です。

投稿2021/05/30 11:32

Serbonis

総合スコア586

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

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

TaroToyotomi

2021/05/30 12:06 編集

要件を見る限り最大99桁の数値の加算なのでこのやりかただと対応できないと思います。
Serbonis

2021/05/30 12:34

質問者の質問の意図が 「ポインタ構造体を実際の値(入力した値)に戻すにはどうしたらいいか」という事でしたので、ポインタの操作に習熟されていない部分があると思い、まずは処理の流れの概要を示したものです。変換関数の適正な実装は質問者の方ご自身で行ってもらえればと思っています。
Savanof

2021/05/30 13:48

今までずっとPythonしか書いた事が無く、多倍長計算の意図が理解できず、かなりちぐはぐ質問になってしまいました。ポインタ構造体の処理についての意図はserbonisさんの汲み取ってくれた意図どおりでした。 ありがとうございます。
Serbonis

2021/05/30 13:56

問題の主意は通常の整数型では扱えない大きな数の処理ですので、私の回答はその意味では使え無いものでした。
guest

0

Int_Add関数の要件上、ポインタを渡す事になっているため、ポインタの指す値を入手する(できていない)

longint_add のことだと思って回答します。
p->val[0]p の指す数値の最初の桁が取得できます。 1234 なら 1
fgets を使うと入力した文字列の最後にヌル文字が代入されるので、
ヌル文字の直前が最も下の桁になります

Int_Add関数の中で引数をint型やfloat型などに変更して、足し算を行う。(できていない)

MAX_INPUTが100ということは最大で99桁の整数を表す文字列が入力されます。
intやlongなどの組み込み型を使ってもせいぜい20桁までしか扱えないので
文字列を整数に変換してもダメだと思います。
二つの整数を表す文字列を、下の桁から走査して足し合わせていきましょう。
結果はもちろん文字列として格納する必要があります
そうすると pAdd_Answer1 に格納用の配列を設定する必要があります

投稿2021/05/30 12:39

jamjam3

総合スコア165

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

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

Savanof

2021/05/30 13:47

今までずっとPythonしか書いた事が無く、多倍長計算の意図が理解できず、かなりちぐはぐ質問になってしまいました。その様に計算します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問