🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

3回答

1482閲覧

テストパターンを作成したいです

ht3433

総合スコア19

C

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

0グッド

0クリップ

投稿2019/12/26 08:18

編集2019/12/26 08:32

テストパターンを作成したいです。
作成したのは、inet_ntopなのですが、様々なネットワークアドレス構造体についてそれが変換可能なものかをテストしたいです。
下記は、inet_ntopのmanページです。
今回はAF_INETの場合を考えます。
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/inet_ntop.3.html

具体的には、
"130.0.7.23"はOKですが、
"130.00.7.23"や"130.01.7.23"はNGというふうにテストしたいです。
mainでテストパターンを作成しましたが、一つしか作成できません。
原因として、もし2つ以上つくってしまうと変数の中身が上書きされてしまうというのは分かっています。
ですが、どうすればテストパターンをいくつも作成することができるのか分かりません。

あと、本題とはそれる事なのですが、a.s_addr = inet_addr("127.256.0.");というふうに、エラーとなる場合でコンパイルして実行すると、
255.255.255.255と表示されます。
私として、エラー表示がされるよう作成したつもりなので、なぜこのように表示されるのか分かりません。

大変恐縮ではございますがお力添えいただければ幸いです。
宜しくお願い致します。

C言語

1#include <stdio.h> 2#include <string.h> 3#include <errno.h> 4#include <arpa/inet.h> 5#define p ( ( const unsigned char* )src ) 6 7const char* inet_ntop( const void* src, char* dst, socklen_t cnt ){ 8 9 // 変数の宣言 10 char buf[sizeof "255.255.255.255"]; 11 12 // srcの数値を文字列に変換 13 const unsigned n = 1 + sprintf( buf, "%u.%u.%u.%u", p[0], p[1], p[2], p[3] ); 14 15 // 文字列がdstのサイズを超えているか判定 16 if ( cnt < n ) { 17 errno = ENOSPC; 18 return( NULL ); 19 20 // 変換した文字列をdstにコピー 21 }else{ 22 23 return( ( const char* )memcpy( dst, buf, n ) ); 24 } 25} 26 27int main(){ 28 struct in_addr a; 29 char dst[256]; 30 31 a.s_addr = inet_addr( "130.0.7.23" ); 32 33 if ( inet_ntop( &a, dst, sizeof dst ) ) { 34 printf( "%s\n", dst ); 35 return( 0 ); 36 }else{ 37 return( 1 ); 38 } 39}

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

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

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

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

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

y_waiwai

2019/12/26 08:20

あなたのいうテストパターンというのは何でしょうか。 意味不明です
ht3433

2019/12/26 08:22

コメントしていただき、ありがとうございます。 ただいま修正致します。
SHOMI

2019/12/26 08:25

>255.255.255.255と表示されます 理由はmanページに書いてありますよ https://linuxjm.osdn.jp/html/LDP_man-pages/man3/inet_aton.3.html inet_addr() 関数は、インターネットホストのアドレス cp を、 IPv4 の数値とドットによる表記からネットワークバイトオーダでの バイナリ値へ変換して返す。 入力が不正な場合、 INADDR_NONE (普通は -1) を返す。 -1 は有効なアドレス (255.255.255.255) なので、この関数を使うと 問題になるかもしれない。
ht3433

2019/12/26 08:36

コメントしていただき、ありがとうございます。 なるほど、そういうことだったんですね。 勉強になります。
ht3433

2019/12/26 08:37

y_waiwaiさん 先ほど、質問の修正をし、テストパターンについて記述いたしました。
SHOMI

2019/12/26 08:49

>もし2つ以上つくってしまうと変数の中身が上書きされてしまう テスト通過後次の結果で上書きされても問題ないと思いますが
ht3433

2019/12/26 09:00

コメントしていただき、ありがとうございます。 このソースコードだと、テスト通過する前に上書きされると思うのですが、 違うのでしょうか?
SHOMI

2019/12/26 09:02

>テスト通過する前に上書きされると思うのですが テスト一つしかありませんが、どこのことを言われていますか?
ht3433

2019/12/26 09:07

ソースコードには1つしかありませんが、例えば、 a.s_addr = inet_addr( "130.0.7.23" ); a.s_addr = inet_addr( "130.1.7.23" ); とした場合、a.s_addrの中身は "130.1.7.23"に上書きされるので、"130.0.7.23"のテストができないということです。 説明不足ですみません。
SHOMI

2019/12/26 09:12

"130.0.7.23"についてのテストが完了してから a.s_addr = inet_addr( "130.1.7.23" ); を実行すればよいだけでは?
ht3433

2019/12/26 09:18

つまり、下記のようにすればよいということでしょうか? a.s_addr = inet_addr( "130.0.7.23" ); if ( inet_ntop( &a, dst, sizeof dst ) ) { printf( "%s\n", dst ); }else{ return( 1 ); } a.s_addr = inet_addr( "130.1.7.23" ); if ( inet_ntop( &a, dst, sizeof dst ) ) { printf( "%s\n", dst ); return( 0 ); }else{ return( 1 ); }
SHOMI

2019/12/26 09:42

そうです。 今は数が少ないので問題ないでしょうが、dstの中に意図したとおりの結果が格納されているかのチェックもprintfによる目視ではなく、プログラム側でチェックした方がよいと思います。 あと、main()でreturnすると終わってしまうので、別関数にするなり不合格を示すprintf等に置き換えるなりして下さい。
ht3433

2019/12/27 02:17 編集

コメントしていただき、ありがとうございます。 確かに、目視よりプログラム側でチェックした方がいいですよね。 >あと、main()でreturnすると終わってしまう これはなにがいけないのでしょうか?下記のコードのようにしても問題ないと思うですがどうでしょうか?あと、テストパターンの作成を2つ以上作ることに関しては、一応できました。 何かアドバイスをいただけるとありがたいです。 ソースコード int main(){ struct in_addr a; char dst[256]; a.s_addr = inet_addr( "130.0.7.23" ); assert( a.s_addr != INADDR_NONE ); a.s_addr = inet_addr( "256.0.7.23" ); assert( a.s_addr != INADDR_NONE ); inet_ntop( &a, dst, sizeof dst ); return( 0 );
SHOMI

2019/12/27 03:06

>これはなにがいけないのでしょうか 一件でもNGとなればその時点で終了するという方針なのであれば問題ありません。
ht3433

2019/12/27 03:51

コメントしていただき、ありがとうございます。 一件でもNGとなればその時点で終了するという方針でやっていたので、よかったです。 ご指摘ありがとうございました。
SHOMI

2019/12/27 04:19

新しいコードはinet_addrの結果のチェックで、inet_ntopのテストをしていませんよ…
guest

回答3

0

自己解決

c言語

1#include <stdio.h> 2#include <string.h> 3#include <errno.h> 4#include <arpa/inet.h> 5#define p ( ( const unsigned char* )src ) 6 7const char* inet_ntop( const void* src, char* dst, socklen_t cnt ){ 8 9 // 変数の宣言 10 char buf[sizeof "255.255.255.255"]; 11 12 // srcの数値を文字列に変換 13 const unsigned n = 1 + sprintf( buf, "%u.%u.%u.%u", p[0], p[1], p[2], p[3] ); 14 15 // 文字列がdstのサイズを超えているか判定 16 if ( cnt < n ) { 17 errno = ENOSPC; 18 return( NULL ); 19 20 // 変換した文字列をdstにコピー 21 }else{ 22 23 return( ( const char* )memcpy( dst, buf, n ) ); 24 } 25} 26 27int main(){ 28struct in_addr a; 29char dst[256]; 30 31a.s_addr = inet_addr( "130.0.7.23" ); 32assert( a.s_addr != INADDR_NONE ); 33 34a.s_addr = inet_addr( "256.0.7.23" ); 35assert( a.s_addr != INADDR_NONE ); 36 37inet_ntop( &a, dst, sizeof dst ); 38return( 0 ); 39}

投稿2019/12/27 03:54

ht3433

総合スコア19

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

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

0

様々なネットワークアドレス構造体

と,それらがOKかNGかを表すデータを(配列なり何なりで)用意して,inet_ntop()の結果と照らし合わせるループでも書けばよいのではないでしょうか.

投稿2019/12/26 08:46

fana

総合スコア11985

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

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

0

以下のようなテキストファイルを作成し、それを1行ごとに処理されてはいかがでしょうか。

130.0.7.23
130.00.7.23
888.999.333.000

C

1int main() 2{ 3 struct in_addr a; 4 char dst[256]; 5 FILE *fp; 6 char buff[256]; 7 int len; 8 in_addr_t ret; 9 fp = fopen("test.txt","r"); 10 if (fp == NULL){ 11 printf("file open error\n"); 12 return(10); 13 } 14 while(1){ 15 memset(buff,0x00,sizeof(buff)); 16 if (fgets(buff,sizeof(buff)-1,fp) == NULL) break; 17 len = strlen(buff); 18 buff[len-1] = '\0'; //改行の削除 19 printf("data=<%s>\n",buff); 20 a.s_addr = inet_addr(buff); 21 22 if (inet_ntop(&a, dst, sizeof dst)) { 23 printf("%s\n", dst); 24 } else { 25 printf("inet_ntop error\n"); 26 } 27 } 28 fclose(fp); 29 return(0); 30} 31

投稿2019/12/26 08:45

編集2019/12/26 09:40
tatsu99

総合スコア5493

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

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

ht3433

2019/12/26 09:04

回答していただき、ありがとうございます。 tatau99さんがおっしゃっているのは下記のように書けばよいということでしょうか? a.s_addr = inet_addr( "130.0.7.23" ); if ( inet_ntop( &a, dst, sizeof dst ) ) { printf( "%s\n", dst ); }else{ return( 1 ); } a.s_addr = inet_addr( "130.00.7.23" ); if ( inet_ntop( &a, dst, sizeof dst ) ) { printf( "%s\n", dst ); return( 0 ); }else{ return( 1 ); }
tatsu99

2019/12/26 09:39

mainのみかいてみました。 ファイル名は"test.txt"であることが前提です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問