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

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

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

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

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

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

配列

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

Q&A

解決済

1回答

1083閲覧

char型の配列を文字コード変換し、int型の配列にしたい

退会済みユーザー

退会済みユーザー

総合スコア0

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

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

integer

integerは、一般的に整数を表します。プラスやマイナス、ゼロもなりうる全ての数です。(例 : -2, -1, 0, 1, 2...)

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

配列

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

0グッド

0クリップ

投稿2020/05/18 23:59

編集2020/05/19 01:55

前提・実現したいこと

コンソールから数字を読み込み、ソートするプログラムを作っています。
数字以外の文字列が入力された際にエラーを返すために、
getcharでcharとして受け取り、空白を区切りとして文字列から-'0'をして数字か判定しました。

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

①char型からint型への配列の変換
②作成したソート関数は数値に対するものなので、char型で渡すと結果がおかしくなりました。
③メモリアクセス違反が発生しています。

ハンドルされない例外が 0x7A9CC920 (ucrtbased.dll) で発生しました(sort.exe 内): 0xC0000005: 場所 0x00000001 の読み取り中にアクセス違反が発生しました。 ハンドルされない例外が 0x7A9CC920 (ucrtbased.dll) で発生しました(sort.exe 内): 0xC0000005: 場所 0x00000001 の読み取り中にアクセス違反が発生しました。

該当のソースコード

C

1//コンソールから数値の入力を一行で受けて、小さい順にソートして返すプログラム 2#include <stdio.h> 3#include <time.h> 4#include <stdlib.h> 5#include <math.h> 6#include <limits.h> 7#include <ctype.h> 8 9 10int getnum(char, int); 11int input_num(char, int, long); 12void swap(int* x, int* y); 13/* ソート関数の宣言 14今はchar型になっていますが、これはテストのためです */ 15char bubble(char*, int); 16char quick(char*, int, int); 17char choice(char*, int); 18char insertion(char*, int); 19char kiguu(char*, int); 20//もとはこのようでした 21//long* kiguu(long*, int); 22 23 24 25int main(void) { 26 27 int sorts, keep[4], i = 0, yoso, input=0, count; 28 double start, end, time; 29 char* base, * endptr; 30 31 //入力の受付 32 printf("いくつの数字をソートしますか?1000以下で指定してください。\n"); 33 char str[1000], buf[5000]; 34 long *longnum; 35 int keta, num = 0; 36 37 /* 38 2~1000の間になるまで入力させる 39 */ 40 count = num; 41 printf("num(桁数指定): %d\n", num); 42 43 44 longnum = (long*)malloc(sizeof(long) * count + 1); 45 46 47 num = 0; 48 printf("\n並び変えたい整数を入力してください。\n"); 49 while (input != count) { 50 51 input = input_num(buf, count*8, longnum); //この部分でエラーになります 52 for(i = 0; buf[i] != '\0';i++){ 53 printf("buf[%d]: %d\ninput: %d\n", i, buf[i], input); 54 } 55 56 } 57 58 printf("\nソートの方法を番号で指定してください。\n1.バブルソート 2.クイックソート 3.選択ソート 4.挿入ソート 5.奇偶転置ソート \n"); 59 60 /* 61 ここからソートの関数に入れますが、こちらはscanfで読み込ませて処理を確認しています。 62 */ 63 64 //結果の表示 65 printf("ソート結果:"); 66 for (int i = 0; i < count; i++) { 67 printf(" %d", buf[i]); 68 } 69 printf("\n"); 70 71 end = clock(); 72 time = end - start; 73 printf("処理時間: %f ms\n", time); 74 75 free(longnum); 76 return 0; 77 78} 79 80//入力された要素を空白ごとに要素として区切り、int型数字にする 81int input_num(char s[], int lim, long longs[]){ 82 83 int c, i, count, keep[1000] = {0}, j = 0, p = 0, yoso_num = 0; 84 85 for (i = 0; i < lim - 1 && (c = getchar()) != '\n'; i++) { 86 s[i] = c; 87 88 89 } 90 count = i; 91 for (i = 0; i < count; i++) { 92 s[i] = s[i] - '0'; 93 94 } 95 96 s[i] = EOF; 97/*下のfor文で条件をs[i]!='\0'にしていましたが、入力から0を受け取った時に処理が終了してしまうので、 98EOFを終了点としました。*/ 99 s[i + 1] = '\0'; 100 count = i; 101 i = 0; 102 keep[p] = s[i]; 103 104 for (i = 1; i < count && s[i] != EOF; i++) { 105 106 if (s[i] == -16) { 107 p++; 108 yoso_num++; 109 i++; 110 keep[p] = s[i]; 111 112 }else{ 113 114 keep[p] = keep[p] * 10 + s[i]; 115 116 } 117 118 } 119 yoso_num++; 120 121 keep[p + 1] = '\0'; 122 for(j = 0; j < p + 2; j++) { 123 longs[j] = atol(keep[j]); //ここでエラーが発生します。 124 } 125 126 127 128 return yoso_num; 129} 130

ソースコードが長くなってしまうので、他の関数は表示していませんが、コメントくだされば適宜追加します。

試したこと

・メモリアクセス違反は宣言外のメモリにアクセスしてしまうこと、と分かったのですが、
宣言し、mallocで確保しているlongnumの0番目でなぜエラーが起こるのかわかりません。

・int型に変換するためには配列内の要素を1つずつatoiで変換しようと思ったのですがこれはいかがでしょうか?

ツールのバージョンなど

Windows10 64bitでVisual Studio2017を使用しています。

###補足情報
文字列配列の扱いで、こちら(知恵袋)も参考にしました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

文字コード変換とか難しいこと考えなくても、そのまま代入すればいいだけです。
char型というのは文字型ではありません
1バイト幅の整数型です


longs[j] = atol(keep[j]); //ここでエラーが発生します。

atolという関数は文字列のアドレスを引数に取り、数値変換した結果を返す関数です。
エラーが出るのはアドレスではなく数値データを引数に与えているせいです

#質問の意図に合うように追記

投稿2020/05/19 00:08

編集2020/05/19 02:07
y_waiwai

総合スコア87774

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

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

Zuishin

2020/05/19 00:09

'0' を 0 に直すには変換が必要です。
y_waiwai

2020/05/19 00:12

ましかし、ソートするということであるなら0に直す必要もあるんやらどないやら
退会済みユーザー

退会済みユーザー

2020/05/19 00:15

atoiを使用しても同じようにエラーになることは確認しているのですが、atoiは使用しなくてよいということでしょうか?
Zuishin

2020/05/19 00:16

21 と 123 を比べて正しく 21 が小さいよう判断するには数値に直すのが簡単じゃないかと思います。
y_waiwai

2020/05/19 00:21

atoiは、数字以外の文字が入ってるとエラーになります EOFが入ってると当然エラーですわな #って質問の論点はこっちだった
y_waiwai

2020/05/19 00:33

ああ、ちゃうやんw atolの引数は文字列のアドレスですよ
退会済みユーザー

退会済みユーザー

2020/05/19 01:50

引数に&をつけることで解決できました!ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問