int型をchar型に変換するには
- 評価
- クリップ 0
- VIEW 2,987
一対一通信で1~10の乱数の中から一つのはずれを引くと通信を終了する爆弾ゲームのようなものを作ってるのですが、
実行結果でクライアントから受信した数字が正しく表示されません。1~10の数字を選んでも爆発が起こりません。
char型とint型の比較をするためにwhile ((int)buf != s);という形にしたのですがここに問題があると思われます。
int s;
char c = s + '0';
でint型の数値をchar型の数字に変換する方法があったのですが、この方法は0~9までしか変換できないようです。
どのように書き直せば完成に近づけるでしょうか
教えてもらえるとありがたいです。
[サーバ]
クライアントからの接続待ち
数字を選んでください...1
相手が選んでいます...。
相手の選んだ数字→3733856
数字を選んでください...3
相手が選んでいます...。
相手の選んだ数字→3733856
数字を選んでください...
[クライアント]
相手が選んでいます...。
相手の選んだ数字→ 1
数字を選んでください...2
相手が選んでいます...。
相手の選んだ数字→ 3
数字を選んでください...4
相手が選んでいます...。
サーバ側
#include <stdio.h>
#include <io.h>//基本入出力関数
#include <winsock2.h>
#include<stdlib.h>//乱数
#include<time.h>//乱数
#define BUF_LEN 100//入出力バッファサイズ
int main()
{
WSADATA wsaData;
SOCKET sock0;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
SOCKET sock;
char buf[BUF_LEN];//入出力バッファ
// winsock2の初期化
WSAStartup(MAKEWORD(2, 0), &wsaData);
// ソケットの作成
sock0 = socket(AF_INET, SOCK_STREAM, 0);
// ソケットの設定(アドレス構造体の設定)
addr.sin_family = AF_INET;//インターネットを使用する
addr.sin_port = htons(12345);//サーバ(自分自身)のポート番号
addr.sin_addr.S_un.S_addr = INADDR_ANY;//IPアドレスすべての値指定
//ソケットのディスクリプタとアドエス構造体を結びつける
bind(sock0, (struct sockaddr *)&addr, sizeof(addr));
// TCPクライアントからの接続要求を待てる状態にする(待ちクライアント数指定)
listen(sock0, 5);
// TCPクライアントからの接続要求を受け付ける
printf("クライアントからの接続待ち\n");
len = sizeof(client);
sock = accept(sock0, (struct sockaddr *)&client, &len);
int s;
srand(time(NULL)); //1~10のランダムな数
s = rand()%10+1; //1~10のランダムな数
//送受信処理
do{
printf("数字を選んでください...");
memset(buf, 0, sizeof(buf));//送受信バッファ0クリア
_read(0, buf, sizeof(buf));//キーボードから入力
send(sock, buf, sizeof(buf), 0);//送信
printf("相手が選んでいます...。");
memset(buf, 0, sizeof(buf));
recv(sock, buf, sizeof(buf), 0);//受信
printf("相手の選んだ数字→%s",buf);
} while ((int)buf != s);
printf("爆発しました\n");
// TCPセッションの終了
closesocket(sock);
// winsock2の終了処理
WSACleanup();
return 0;
}
クライアント側
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <io.h>//基本入出力関数
#include <winsock2.h>
#define BUF_LEN 100//入出力バッファサイズ
int main()
{
WSADATA wsaData;
struct sockaddr_in server;
SOCKET sock;
char buf[BUF_LEN];//入出力バッファ
// winsock2の初期化
WSAStartup(MAKEWORD(2, 0), &wsaData);
// ソケットの作成
sock = socket(AF_INET, SOCK_STREAM, 0);
// 接続先指定用アドレス構造体の準備
server.sin_family = AF_INET;//インターネット使用
server.sin_port = htons(12345);//接続先ポート番号
server.sin_addr.S_un.S_addr = inet_addr("*.*.*.*");//接続先IPアドレス
// サーバに接続
connect(sock, (struct sockaddr *)&server, sizeof(server));
//受信送信処理
int n = 1;
do {
memset(buf, 0, sizeof(buf));//送受信バッファ0クリア
printf("相手が選んでいます...。");
recv(sock, buf, sizeof(buf), 0);//受信
printf("相手の選んだ数字→ %s\n",buf);
printf("数字を選んでください...");
memset(buf, 0, sizeof(buf));//送受信バッファ0クリア
_read(0, buf, sizeof(buf));//キーボードから入力
send(sock, buf, sizeof(buf), 0);//送信
} while (n = 1);
printf("爆発しました\n");
// TCPセッションの終了
closesocket(sock);
// winsock2の終了処理
WSACleanup();
return 0;
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
C言語で文字列を数値にするには atoi を使います。
while (atoi(buf) != s);
ただし気を付けないといけないのは atoi は例えば数字でない物を入力した場合でも 0 になってしまいます。つまり本当に 0 を入力したのか abc を入力したのか分からないという事です。
これを解決するには strtol という関数を使います。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char* argv[]) {
int n;
char *err = NULL;
char buf[20];
strcpy(buf, "1s"); // サンプルの入力
n = strtol(buf, &err, 10);
if (err != NULL) {
printf("入力エラーです。エラーの位置は: %s\n", err);
} else {
printf("入力した数値は %ld です\n", n);
}
return 0;
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
まず、C言語で文字列は文字型の配列として扱われ、配列どうしの比較演算は定義されていない事(つまり、文字列同士の比較は==や!=では行えないという事)を念頭に置いて、この後の話を読んでいだたきたいと思います。
まず、(int)bufを
printf("%d\n",(int)buf);
のようにして書き出してみてください。
恐らく適当な値(数十万程度)が出力されると思います。
それをsと比較すると、絶対に一致するはずのないことがわかります。
これは、bufはbuf配列の先頭アドレスを示しており、(int)bufはそのアドレスをint型にキャストしたものになってしまうからです。
ですので、まずはbuf配列の中身を数字として書き出す必要があります。
C++を使っているのであれば数ステップで変換できるのですが、C言語だと些か面倒ですので、範囲を1-10に限定したコードを例示します。
const int ABNORMAL -1;
int buf_i;
if(strlen(buf)==1){
buf_i = buf[0]-'0';
}
else if(buf[0]==1 && buf[1]==0){
buf_i = 10;
}
else{
buf_i = ABNORMAL;
}
このコードの後に、
if(buf_i != ABNORMAL){
//処理
}
などを使って10以外の数値が入力された場合の処理をかけばいいとおもいます。
質問者様の意図に沿った回答ができているか不安ですので、わからない場合は返信していただければお答えいたします。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
WoodenHamlet
2017/08/03 08:45
この質問とは直接関係ないからこっちに書くけど、クライアント側のDo-while文の判定式、while(n=1)としているけど、(n=1)の値は常に1…真になるので無限ループに陥ってますよ