こんにちはCについて質問があります

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fuguo

こんにちはCについて質問があります

#1

投稿記事 by fuguo » 18年前

入力した文字が数だけなら1
文字列が含まれていたら2
を返すプログラムを作りました。


//ここから//
#include<stdio.h>
#include<string.h>
#include<windows.h>
//入力するとこ//
int nrk(long *);

int main(void)
{
long motikin;
do{
printf("かずを入力してください。");
nrk(&motikin);
}while(1);
return 0;
}
//入力するとこ//
int nrk(long *kazu)
{
int i,l;
int co;
long ren;
char *kam;

*kazu=0;

gets(kam);

ren=strlen(kam);

for(i=0;i<ren;i++){
co=1;
for(l=0;l<ren-1-i;l++){
co*=10;
}
if(kam-'0'<0||kam-'0'>9){ 
return 2;
}
*kazu+=(kam-'0')*co;
}
return 1;
}
//ここまで//

while文の1週目まではうまくいきます。2週目からは"数を入力してください。"が表示されません。
それに入力した文字が表示されます。
どなたかわかる方お願いします。

Hermit

Re:こんにちはCについて質問があります

#2

投稿記事 by Hermit » 18年前

とりあえず、
char *kam;
の部分は、ポインタしか確保されていないので、
どこかわからない領域に入力された文字列が確保されますので、
char kam[256];
などの様に、格納される領域を確保した書き方のほうがいいと思います。

box

Re:こんにちはCについて質問があります

#3

投稿記事 by box » 18年前

> 		nrk(&motikin);

nrk関数でmotikinの内容を変更していますが、
変更した内容を使っていません。
また、nrk関数の戻り値も使っていません。
そのあたりは、今後追加される予定ですか?

fuguo

Re:こんにちはCについて質問があります

#4

投稿記事 by fuguo » 18年前

boxさん はい、今後追加する予定です。

Hermitさん ありがとうございます!!配列にするとできました。
でもこのようにすることはできないんですかね?

#include <stdio.h>

int main() {
char *str = "YUKI \0 RENA \0 MIMI";
printf("%s\n%s\n%s" , str , str + 7 , str + 14);
return 0;
}

このようにしてみたら

#include<stdio.h>
#include<string.h>
//入力するとこ//
int nrk(long *);

int main(void)
{
long motikin;
do{
printf("かずを入力してください。");
nrk(&motikin);
}while(1);
return 0;
}
//入力するとこ//
int nrk(long *kazu)
{
int i,l;
int co;
long ren;
char *kam;

*kazu=0;

gets(kam);

ren=strlen(kam);

for(i=0;i<ren;i++){
co=1;
for(l=0;l<ren-1-i;l++){
co*=10;
}
if((kam+i)-'0'<0||(kam+i)-'0'>9){
return 2;
}
*kazu+=((kam+i)-'0')*co;
}
return 1;
}

こうなりました。ですが

警告 W8066 test.cpp 13: 実行されないコード(関数 main() )
エラー E2034 test.cpp 34: 'int' 型は 'char *' 型に変換できない(関数 nrk(long *) )
エラー E2087 test.cpp 37: ポインタの不正な使用(関数 nrk(long *) )
*** 2 errors in Compile ***

のようなエラーが出ます。
やはり無理でしょうか?

バグ

Re:こんにちはCについて質問があります

#5

投稿記事 by バグ » 18年前

*kazu+=((kam+i)-'0')*co;

詳しくは見てないので、ざっと見ただけですが…この表記がまずそうですね。アドレスと実体がごちゃ混ぜになってます(;^_^A

box

Re:こんにちはCについて質問があります

#6

投稿記事 by box » 18年前

(略)
> このようにしてみたら
(略)
> こうなりました。ですが

引用を省略した2つのコードの関係が全然わかりません。
1つ目のコードはmain関数だけから成る、2つ目のコードとは
無関係なものであるように見えます。
にもかかわらず、「こうしたらこうなった」と、
2つのコードに関係があるかのごとく書かれているのが理解できないです。

むつ

Re:こんにちはCについて質問があります

#7

投稿記事 by むつ » 18年前

逆に「どの辺りが問題だと思いますか?」と質問したら答えられるでしょうか。
恐らく問題が複雑に絡み合っている為、特定が難しくなっていると思います。

そこで、while内で入力したら表示させるだけのシンプルなプログラムを先に作りましょう。
※ヒント:while(!feof(stdin))
※gets()を使用していますが、用意したバッファサイズを超える文字列が入力された場合、
不正アドレスにアクセスする恐れがある為、fgets()やgetchar()を使用する等した方がいいと思います。

数値・文字判定は、ctype.hを調べるといいかもしれません。
※isalpha()等の引数はunsigned charかEOFとなっています。

Hermit

Re:こんにちはCについて質問があります

#8

投稿記事 by Hermit » 18年前

>でもこのようにすることはできないんですかね?
出来ます。が、前回の質問との関連はあまりなさそうですが・・・

>#include <stdio.h>
>int main() {
> char *str = "YUKI \0 RENA \0 MIMI";
ここの str は、プログラムコードの書き換え不能エリアにある
"YUKI \0 RENA \0 MIMI" の文字列の先頭位置のアドレスで、
str を初期化しています。

> printf("%s\n%s\n%s" , str , str + 7 , str + 14);
で、ここで、str の位置、str+7 番目の位置、str+14 番目の位置からの文字列を読み出しているだけで、
書き換えを行っていない為、問題ありません。
また、
printf("%s\n",str);
printf("%s\n"str+=7);
printf("%s\n"str+=7);
の様に、str 自体は変更可能です。

ここで、char *str ではなく、
char str[/url] = "YUKI \0 RENA \0 MIMI";
のように書いた場合の違いは、

ひとつに、
文字列が、書き換え可能エリアに確保されるという事。
だから、文字列の変更は可能です。
str[5] = '\t'; str[12] = '\t'; などしてみればわかるかな?

もうひとつが、
str 自体のアドレスは変更できないという事。
(str,str+7,str+14 のような書き方は出来ます。str 自体を変えていないので)

表示だけの場合は、見た目は同じですけど(^^;

ふぐお

Re:こんにちはCについて質問があります

#9

投稿記事 by ふぐお » 18年前

皆さん、まことにありがとうございました。

バグさん ありがとうございます。

boxさん 僕の国語力がないばかりに、貴方をいやな思いにさせてすいませんでした。
僕が言いたかったのは printf("%s\n%s\n%s" , str , str + 7 , str + 14); のように          *kazu+=(kam-'0')*co; も *kazu+=((kam+i)-'0')*co; できないかなーって思い質問させていただきました
説明不足で失礼しました。

むつサン 優しいヒントをありがとうございました。

Hermitさん いろいろ勉強になりました。ありがとうございました。



みなさんお礼に完成したプログラムで遊んでくれ

#include<stdio.h>
#include<stdlib.h>
#include<process.h>
#include<string.h>
#include<conio.h>
#include<time.h>
#include<windows.h>

#define DAME if(hantei==2)printf("不正な文字を入力しないでください。\n\n\n");

void endk(void);
void kakehantei(int,long,long *);
void antei(int,long *);
void nyuryoku(int,long *);
int nrk(long *);
int ran(int,int);


long buf;
FILE *file;
int buf2[256];
int save;
long mend;

int main(void)
{
int ran1,ran2,saikoro,i;
int hantei;
char kekka[1];
char namev[256];
long motikin,kakekin=0
,choha=0;
file = fopen("save.dat","a+");
fread(&buf,sizeof(buf),1,file);
fclose(file);
if(buf==0){
printf("最高点なしじゃ!!\n\n");
}else{
printf("最高点%dじゃ!!",buf);
file = fopen("name.dat","a+");
fread(buf2,sizeof(buf2),1,file);
fclose(file);
for(i=0;i<256;i++){
namev=buf2;
}
printf("%sチャンじゃ!!\n\n",namev);
}
Sleep(500);
printf("持ち金の設定を100にして、end 入力で終わると、\nセーブされます。");

nyuryoku(1,&motikin);
if(motikin==100)save=1;
while(1){
if(save==1)mend=motikin;
kakehantei(2,motikin,&kakekin);
antei(3,&choha);
printf("\n");
ran1=ran(1,6);
ran2=ran(1,6);
saikoro=(ran1+ran2)%2;
if(saikoro==1){
strcpy(kekka,"半");
}else{
strcpy(kekka,"丁");
}
printf("サイコロ1= %d\nサイコロ2 =%d\n合計 %d <%s>です。\n\n",ran1,ran2,ran1+ran2,kekka);
if(saikoro==choha){
motikin+=kakekin;
}else{
motikin-=kakekin;
if(motikin<=0){
Sleep(700);
printf("もうお金がありません。\nさよなら。");
Sleep(2000);
break;
}
}
printf("あなたの持ち金は%dです。\n\n",motikin);
}
return 0;
}


int nrk(long *kazu)
{
int i,l;
int co;
long ren;
char kam[256],end[/url]="end";
*kazu=0;
gets(kam);
if(strcmp(kam,end) == 0){
endk();
}

ren=strlen(kam);

for(i=0;i<ren;i++){
co=1;
for(l=0;l<ren-1-i;l++){
co*=10;
}
if(kam-'0'<0||kam-'0'>9){
return 2;
}
*kazu+=(kam-'0')*co;
}
return 0;
}

void nyuryoku(int A,long *kazu)
{
int hantei;
do{
DAME;
switch(A){
case 1:
printf("持ち金を入力してください。-->");
break;
case 2:
printf("掛け金を入力してください。-->");
break;
case 3:
printf("\n丁=0,半=1 -->");
break;
}
hantei=nrk(kazu);
}while(hantei==2);
return;
}

int ran(int min,int max)
{
static int flag;

if (flag == 0) {
srand((unsigned int)time(NULL));
flag = 1;
}

return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
}

void antei(int yu,long *kazu)
{
do{
nyuryoku(yu,kazu);
if(*kazu<0||1<*kazu){
printf("不正な文字を入力しないでください。\n\n");
}
}while(*kazu<0||1<*kazu);
return;
}

void kakehantei(int yu,long moti,long *kazu)
{
do{
if(moti<*kazu){
printf("そんなことあるか?");
}
nyuryoku(yu,kazu);
}while(moti<*kazu);
return;
}

void endk(void)
{
int ren,i;
int namex[256];
char name[256];

if(save==1){
file = fopen("save.dat","r");
fread(&buf,sizeof(buf),1,file);
fclose(file);
if(buf<mend){
file = fopen("save.dat","r+");
fwrite(&mend,sizeof(mend),1,file);
fclose(file);
printf("記録を更新しました!!\n名前をいれてね。");
gets(name);
ren=strlen(name);
for(i=0;i<=ren;i++){
namex=name;
}
file = fopen("name.dat","w");
fwrite(namex,sizeof(namex),1,file);
fclose(file);
}
}
printf("さようならノシ");
Sleep(1300);
exit(0);
return;
}
 
 

むつ

Re:こんにちはCについて質問があります

#10

投稿記事 by むつ » 18年前

感想:お金がなくなるまで賭け続ける・・シビアなゲームだ。

閉鎖

“C言語何でも質問掲示板” へ戻る