Cプログラム初心者です。
例えば、floatの名前をlengthとして、scanfでユーザーに入力させるとします。その時ユーザが間違えて数字ではなく文字を入力した場合、その後のprintfの内容がループしてしまいます。どうしたら、ユーザーが間違えて入力したときに、入力ミスを伝え、もう一回入力をしてもらうことができるプログラムが作れるでしょうか。
以下がエラー処理をする前のプログラムの一部なのですが、、、。

float length;

printf("Enter length of the room in metre and press enter.\n");
scanf("%f", &length);
while (length>300)
{

printf("This programme only caluculate length under 300m.\n");
printf("Please re-enter the length in metre and press enter.\n");
scanf("%f", &length);

}/*End of while (length)*/

A 回答 (4件)

どのレベルまでのエラーチェックが必要かが不明ですが…


私ならfgets()->strtod()という手順を踏みます。

・scanf()は入力を消費しない
scanf()はエラーを返したときに入力内容を消去しません。
結果、いとも簡単に無限ループに陥ります。
エラー派生時には入力バッファのフラッシュをする必要があります。
・gets()は入力文字数を制限できない
gets()は文字列入力関数ですが、入力文字数を制限する機能がありません。
結果、想定しない文字数を入力される可能性があります。
これは、scanf()で%sを使ったときも同じです。
(sanf()の場合は回避法アリ)
・atof()は変換不能文字を報告しない
atof()はエラーを報告する手段をもちません。
入力 出力
0.0  0.0
abc  0,0
1.0  1.0
1.b  1.0
abcや1.bという数値はありません。これらはエラーのはずですが、atof()にエラー報告の機能が無いために「変換可能だった文字だけを変換した結果(1.b→1.0)または、0.0(abc→0.0)」が返されます。

char *fgets()は入力文字の最大数を制限できます。
fgets(char *入力文字列用の配列,int 入力可能文字数+1,stdin);
入力可能文字数+1なので単純に配列のよう素数を指定すればオッケーです。
(入力文字の最後に'\0'が付加されるため「入力可能文字数+1」を指定します)
キーボード入力を受け取る場合最後の引数をstdinとします。

strtod()は変換不能文字を発見したときに、その文字のアドレスを報告します。
結果、1.bやabcなどという「数字として認識不能な並び」を発見できます。
double strtod(char *変換する文字列,char **変換不能文字のアドレス);

キーボード入力の場合の例)
double len ;
char str[10], *trm ;

if (fgets(str, sizeof(str), stdin) == NULL){
/* 9文字以内の文字列をキーボードから入力 */
/* fgets()がNULLを返したときは"入力無し”かエラー */
エラー処理
}

len = strtod(str, &trm) ; /* 文字列→浮動小数点変換 */
if (trm != NULL && (*trm != '\0' || *trm != '\n')) {
/* 変換不能文字が'\0'か改行なら入力は数値、それ以外なら数値以外の入力 */
printf("数値以外が入力された:%s", str) ;
エラー処理
}
/* lenに入力を浮動小数点変換したものが設定されている */
    • good
    • 0
この回答へのお礼

アドバイスありがとうございます。大変複雑な内容をわかりやすく、砕いて説明していただいて感謝しております。まだ始めたばかりですが、ひとつ、ひとつの関数が持つ利点、マイナス点を理解しながら勉強を続けたいと思います。
ありがとうございました。

お礼日時:2002/03/04 09:15

scanf系の関数は想定外の入力に弱いので、


こういうエラー処理を考えるならまず使わないですね。

getsとatofがいいでしょう。
scanfの戻り値でもある程度はわかりますが、
多少厳密さに欠けます。
例えば,"123ABC"と入力した場合、エラーとするか、
123が入力されたとするかという違いです。

あとgetsよりもfgetsの方がバッファオーバーフローがおきなくて本当はいいのですが・・・
    • good
    • 0
この回答へのお礼

早速アドバイス頂きありがとうございます。初心者だと、どうしてもscanfを最初に習うので、数字=scanfなんて思ってしまいがちなんですが、実際には文字入力というのが入力エラーを抑える働きとなるんですね。初心者だと考え付かない、発想です。勉強になりました。ありがとうございました。

お礼日時:2002/03/04 07:46

scanf()の戻り値を使えば良いんでは?


scanf()系の関数は代入に成功した変数の
数を返します。ですから、

float length;
do{

printf("Enter length of the room in metre (<= 300m) and press enter.\n");

} while( scanf("%f", &length) < 1 || length > 300.0f || length < 0.0f);

面倒臭がりなのでwhileの中の条件式で全部判定させましたが、
見易いように分けた方がいいかも知れません。
    • good
    • 0
この回答へのお礼

早速アドバイス頂き、ありがとうございます。試してみます!

お礼日時:2002/03/04 07:37

scanf()は演習用にはよいですが、アプリには使いません。


scanf()は最悪の関数ですから。

文字列として入力させ、入力された文字列が正しいか、チェックして、それを実数に変換します。

文字列入力:gets()
チェックには:isdigita()
などを使うようです。
    • good
    • 0
この回答へのお礼

早速アドバイス頂きありがとうございます。scanfは使わないほうがいいんですね。数字が入力できるから、、という単純な理由でscanfを使ってたんですが。エラーの時に大きな落とし穴と変わるんですね。貴重なアドバイスありがとうございました。

お礼日時:2002/03/04 05:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q404ERROR の 意味の統一はいつからですか?

こんばんは~! ネットワークのカテゴリーのエキスパートな方々!回答宜しく~^^

質問はタイトルの通りなのですが、『404 ERROR』はいつ頃から共通に利用されてるのですか?
仮に最初に統一した人がいるのなら、使用許諾や使用に当っての利点若しくは、お金が来てるの?

Aベストアンサー

HTTPエラーコード404。
Not Found:要求されたURIに対するマッチする情報が見つからない(RFC1945)
通信規約上の約束です。

RFC(Request For Comment:ご意見お待ちしてます)はインターネット標準案と標準規約を記述したメモで、誰でも参照して利用することが出来ます。

いつから?と問われればRFC1945に制定されたメモが発表された1996年からです。

Qprintf("文字列\n")が円マークなんです!!斜線がでない!!

うちのノートパソコン(IBM)OSはTurbolinux Personalと、デスクトップ(NEC)OSはWindows2000でC言語のプログラミングをすると文字が変なんです。

printf("文字列\n");

と改行のエスケープシークエンス?を入力すると円マーク(\)なんです!!

右下がりの斜線のキーを押してるのに円マーク(\)しかでないんです。二つのPCどちらでやってもです。C言語のテキストでは右下がりの斜線とnで改行のエスケープシークエンス?になっているので見ていて気持ちが悪いです・・・。

ちゃんと右下がりの斜線は出せないものでしょうか。ちなみにキーボードには右下がりの斜線が書いてあります。

プログラミング上も\nで右下がりの斜線と同じ、改行の意味で理解されているらしく、ちゃんと改行されます。

でも右下がりの斜線じゃないと気持ち悪い・・・。直せませんか?

Aベストアンサー

日本語環境だと、\で正解です。
同じ意味(文字コード)です。


\(の半角)は バックスラッシュといいます。
日本語フォントでは、歴史的な原因で \ の文字コードと同じものが割り当てられていますので、日本語フォントで表示している限り、 ¥(半角)が表示されます。


歴史的背景をここで解説すると文字数足りなくなりますので。
ここ
http://ja.wikipedia.org/wiki/%5C
や、ここ
http://ja.wikipedia.org/wiki/%E5%86%86%E8%A8%98%E5%8F%B7
を読んでください。

Q404 Error Not Found と出てしまします

初めてホームページを作ろうとしている者なので、専門用語ではなく、わかりやすく教えて下さいませm(__)m
「HETEMULU」を使って、ホームページを作り、半年かけて、やっと完成しました^^;
そして、無料だと聞いたので、「忍者ホームページ」サイトで、
「NINJA TOOLS」?という所で、IDやパスワードを取得し、なんとか出来たと思ったのですが、

登録されているあなたのURL

とい所をクリックすると、

404 Error Not Found と出てしまします。

何故ですか??

色々触ってみたけど、わかりません^^;

もう一つ質問ですが、無料素材屋さんから、画像をダウンロードして、
「名前をつけて保存」と書いてあったので、例えば「鉢植え」と保存しました。「HETEMULU」で画像の挿入をクリックすると、「鉢植え」の後ろに.gifと付き、問題ないように思っているのですが、日本語で保存しているから、404 Error Not Found と出てしまうのでしょうか?それともそれはまったく関係ないのでしょうか?
慣れていらっしゃる方にはおバカな質問かもしれませんが、どうかどなたか教えて下さい!説明が足りなければ補足しますので、どうかよろしくお願いします!!!

初めてホームページを作ろうとしている者なので、専門用語ではなく、わかりやすく教えて下さいませm(__)m
「HETEMULU」を使って、ホームページを作り、半年かけて、やっと完成しました^^;
そして、無料だと聞いたので、「忍者ホームページ」サイトで、
「NINJA TOOLS」?という所で、IDやパスワードを取得し、なんとか出来たと思ったのですが、

登録されているあなたのURL

とい所をクリックすると、

404 Error Not Found と出てしまします。

何故ですか??

色々触ってみたけど、わか...続きを読む

Aベストアンサー

作成したHTMLファイルをサーバーにアップロード(転送)済みで
しょうか?
トップページは必ず「index.html」または「index.htm」である
必要があります。
「index.htm」にする場合は、元からある「index.html」を削除
(※下記ページ参照)
http://www.ninja.co.jp/faq/a/37/

おすすめのFTPソフト
「FFFTP」
http://www2.biglobe.ne.jp/~sota/

日本語ファイルは表示されない場合もあるので、英数字のファイル名
が推奨されています。
http://www.ninja.co.jp/faq/a/79/

Qprintf("\a");のアラーム音

言語:c

#include <stdio.h>

int main ( void ) {
printf("\a");
return (0);
}

上記のプログラムを実行すると、
アラーム音(?)が鳴ります。

音が出ている場所がスピーカからではなくて、
PCの本体から出ているようです。

なぜスピーカから鳴らないのでしょうか。
なぜPC本体から鳴っているのでしょうか。

Aベストアンサー

環境にもよるのですが…Windowsですか?一般的なPCの場合、
スピーカからなる宇和揺る普通のサウンドの他に、BEEP音源というのがありまして。
こちらはデバイスが違うのでPC本体から直接音が鳴ります。
# 現在では、例えばシステムの異常を通知するような時くらいしか使われないかも。
で、\aにこちらが使われるのは、多分にMS-DOS時代からの歴史的な経緯じゃないかと思います。
昔はコレでも普通でしたし、
\aは「何か音がなればいい」というものであって、どんな音を鳴らすかは別に決まってないですし、
めったに使われないので綺麗なサウンドとか必要ないと思いますし、
OSがおかしくてもなる可能性がBEEPの方が高いかもしれませんし…。

Q教えて下さい!なぜ【WebApp: Error 404】のページが出る?

JDK + apache + mod_webapp.so + tomcat + PostgreSQLをインストール・設定しました。

JDK     j2sdk-1_3_1_11-linux-i586
apache    apache1.3.31
mod_webapp.so
tomcat    jakarta-tomcat-4.1.30
PostgreSQL    postgresql-7.2.3

(1)
http://localhost:8080/index.jsp
【tomcat】のページが出ます。

(2)
http://localhost/
【あなたの予想に反して、このページが見えているでしょうか?】のページが出ます。

(3)
http://localhost:8080/examples/jsp/index.html
【JSP Samples】のページが出ます。

(4 問題点)
http://localhost/examples/jsp/index.html
【WebApp: Error 404】のページが出ます。
希望 → (3)と同じページが出る。

起動は tomcat → apache の順です。

なぜ【WebApp: Error 404】のページが出るのでしょうか?
教えて下さい。
お願いします。
(初心者なので出来ればわかりやすくお願いします)

JDK + apache + mod_webapp.so + tomcat + PostgreSQLをインストール・設定しました。

JDK     j2sdk-1_3_1_11-linux-i586
apache    apache1.3.31
mod_webapp.so
tomcat    jakarta-tomcat-4.1.30
PostgreSQL    postgresql-7.2.3

(1)
http://localhost:8080/index.jsp
【tomcat】のページが出ます。

(2)
http://localhost/
【あなたの予想に反して、このページが見えているでしょうか?】のページが出ます。

(3)
http://localhost:...続きを読む

Aベストアンサー

設定内容が書いていないので
いかんともあれなんですが。。。(^^;
以下の手順をご確認下さい。

1.mod_webapp.soをapacheのlibexecに配置している。

2.apacheのhttpd.confに以下を記述している。
------------------------------------------------------
LoadModule webapp_module libexec/mod_webapp.so
AddModule mod_webapp.c

<IfModule mod_webapp.c>
WebAppConnection warpConnection warp localhost:8008
WebAppDeploy examples warpConnection /examples
WebAppInfo info
</IfModule>
------------------------------------------------------

3.tomcatのserver.xmlに以下を記述している。
------------------------------------------------------
<Service name="Tomcat-Apache">

<Connector className="org.apache.catalina.connector.warp.WarpConnector"
port="8008" minProcessors="5" maxProcessors="75"
enableLookups="true" appBase="webapps"
acceptCount="10" debug="0"/>

<Engine className="org.apache.catalina.connector.warp.WarpEngine"
name="Apache" debug="0">

<Logger className="org.apache.catalina.logger.FileLogger"
prefix="apache_log." suffix=".txt"
timestamp="true"/>

<Realm className="org.apache.catalina.realm.MemoryRealm" />

</Engine>

</Service>
------------------------------------------------------

4.tomcat、apacheの順で再起動

どう?

設定内容が書いていないので
いかんともあれなんですが。。。(^^;
以下の手順をご確認下さい。

1.mod_webapp.soをapacheのlibexecに配置している。

2.apacheのhttpd.confに以下を記述している。
------------------------------------------------------
LoadModule webapp_module libexec/mod_webapp.so
AddModule mod_webapp.c

<IfModule mod_webapp.c>
WebAppConnection warpConnection warp localhost:8008
WebAppDeploy examples warpConnection /examples
WebAppInfo info
</IfModule...続きを読む

Qprintfとscanfの違いって・・・

ふとした疑問がわいたので、質問させていただきます。

なぜ、scanfの時は scanf("%d",&a)のように
アンパサンド&をつけるんでしょうか?

一方、printfだと、prinf("%d",a)のように
アンパサンド&はつけません。

どうして、両方とも関数なのに
アンパサンドをつける、つけないの区別があるんでしょうか?

プログラミングしていて、ふと思ったんですが
なぜなんでしょうか・・・?

Aベストアンサー

scanfはaという変数のある「場所」に"%d"の型で格納すると言うものです。
一方printfではaという変数の「中身」を"%d"という型で出力すると言うものです。
つまりaと表記した場合はaの「中身」を指すことになり、&aと表記された場合はaという変数のある「場所」を指すことになります。

詳しく言うと今aという変数が10と言う場所に割り当てられているとします。そして中身には5と言う数値が入っていたとします。
この場合aのある「場所」は10となり、「中身」は5となります。
&aと書いた場合は「場所」を表すことになりますので、scanfには10が渡されて、格納したい「場所」を指定しています。10と言う場所はaに割り当てられているのでaに格納されることになります。
もしscanfでaと書いてしまった場合は、5と言う数値が渡されてしまい、本来10という場所にあるaとは無関係な5と言う場所にある何かに格納されてしまいます。
これでは思ったとおりの結果にはならないはずです。

まとめるとアドレスか、中身かといえます。

QError!! HTTP status code=404

Error!! HTTP status code=404

いつもお知恵拝借、ありがとうございますm(_ _)m

さて、最近当社で中古XP (prof.)パソコンを2台導入しました。sp3にupしております。

取引先のサイトにアクセスし、IDとpasswordでログインして「取引明細」をダウンロードしようとしましたが、ファイルのアイコンをクリックしたら上記のようなエラーメッセージが出ます。

2台とも同じエラーが出ます。

「教えてgoo」や他のサイトで検索してもなかなか、コレというページが見あたりません。

以前からあるもう一台のXPからはアクセスでき、見ること・プリントすることが出来ます。

アクセスしようとしたファイルは拡張子が".ilf"で、検索の結果どうやら電子帳票のファイルのようです。

このようなトラブルは初体験なので、皆さんのお知恵を是非拝借したいと思います。どうかよろしくお願いいたしますm(_ _)m

Aベストアンサー

ILFのことについてはわかりませんが、単純にHTTP のエラーコード404は、
Not Foundですね。

要するに、指定のページやファイルが見当たらないということ。

先方のシステム内で、指定されたファイルがないということではないですか?
それを先方のWEBサーバーと連携したILFのシステムが応えていると・・・

先方の担当者に聞いた方がいいと思いますが。
特定のシステム内のことですので、担当者以外は本当のことはわかりません。

Qwhileとscanfの関係について

while文中のscanf関数が意図しない動作をして困っています
簡略化したコードがこちらになります
while(1){
// view
printf("view\n");
// input
char key;
scanf("%c", &key);
// update
printf("update\n");
}

行いたい動作というのは単純で
view -> input -> update ->を繰り返したいだけなのですが
上記プログラムでは下記のような動作になってしまいます
view -> input -> update -> view -> update -> view -> input ->
偶数回目のループでは、inputが飛ばされてしまうのですが、何が原因なのかかがわかりません。

言語仕様に詳しい方、どなたかご教示ください。

環境
WindowsXP
Visual C++ 2008 ExpressEdition

Aベストアンサー

scanf()を使用していることに対しての弊害ですね。
scanf()はリターンキーの直前までの入力をキーバッファから取得します。
キーバッファにはリターンキーが残ったままとなっている為、次のscanf()でバッファに残ったものが取り込まれてしまう為に発生する問題です。
「printf("update\n");」の部分でブレークをかけて「key」の入力内容を確認すればわかりますが、偶数回目にはリターンキーのコードが取得されています。
scanf("%c", &key);
scanf( "%*[^\n]" );
のように、取得した内容以降のバッファの読み飛ばしを追加するか
scanf()以外の入力関数でを使用することで回避します。

QHTTP 404 error

Vine Linux,Tomcat5で
(1)webapps/conf/server.xml
...
<HOST>
<Context path="/apress" docBase="apress" debug="0" reloadable="true" />
...
(2)webbapps/apress/login.jsp
...
<table width="500" border="0" cellspacing="0" cellpadding="0">
<form name="loginForm" method="post" action="servlet/chapter2.login">
<tr><td width="402"><div align="right">User Name: </div></td>
<td width="399"><input type="text" name="username"></td>
</tr>
...
(3)webapps/apress/WEB-INF/web.xml
...
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>chapter2.login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
...
(4)webapps/apress/WEB-INF/classes/chapter2/login.java
package chapter2;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class login extends HttpServlet {
private String target = "/welcome.jsp";
private String getUser(String username, String password) {
// Just return a statice name
// If this was reality, we would perform a SQL lookup
return "Bob";
}
....
(4)現象:
http://xxx.xxx.xxx.xxxx:8080/apress/login.jsp
でsubmit action 後、次のエラーが出てきました:
HTTP 404 error,
The requested resource (/apress/servlet/chapter2.login) is not available.

この問題はどこにあるでしょうか教えてください。

Vine Linux,Tomcat5で
(1)webapps/conf/server.xml
...
<HOST>
<Context path="/apress" docBase="apress" debug="0" reloadable="true" />
...
(2)webbapps/apress/login.jsp
...
<table width="500" border="0" cellspacing="0" cellpadding="0">
<form name="loginForm" method="post" action="servlet/chapter2.login">
<tr><td width="402"><div align="right">User Name: </div></td>
<td width="399"><input type="text" name="username"></td>
</tr>
...
(3)webapps/apress/WEB-INF/web....続きを読む

Aベストアンサー

パスの指定が間違ってるからだと思いますが。

/apress/servlet/chapter2.login

このパスにちゃんと存在してますか?

Q改行の書き方('\n' "\n")はどっちの書き方でもいいのでしょうか?

タイトルの通りです。
↑の方法ではどっちもコンパイルできる事が分かったのですが、どっちも正しいですよね?
よろしくお願いします。

Aベストアンサー

受けて側にあわせてやる必要があります

'\n'は文字として相手が受け取る場合です
"\n"は文字列として相手が受け取る場合です

void func1( char ch );
void func2( char* str );
とあった場合 func1には '\n'で渡し fucn2は "\n"で渡します


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング