←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3865

いくら調べても分からないカンマ編集!
投稿者---あきき(2005/06/02 11:57:00)


例えば、符号付の整数または、入力された数値で先頭数値が0で始まるものは無視した(スキップ)上で、カンマ編集を行いたいのですが、以下のプログラムでは何が原因かは定かではありませんが、例えば、-,123,45などと表示されます。一体どこが悪いのでしょうか?勿論、空文はエラー表示されます。

/*** カンマ編集 ***/
///////////////////////////////////////////////////////////////////////////////////
//          カンマ編集処理
///////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define  MAX_SIZE   128

void CommaEdit(char *s);
int  IntdigitChk( const char *p );

int  main(void)
{
    char  buff[MAX_SIZE+1];

    printf("整数を入力してください : \n");
    printf("Input : ");
    //キーボードからの入力か?
    fgets( buff,MAX_SIZE, stdin);
    //数字か?
    if (IntdigitChk(buff)){
        CommaEdit(buff);
    }
    else{
        printf("整数を入力しろといってるだろが!ボケ\n");
    }

    return  0;
}
///////////////////////////////////////////////////////////////////////////////////
//          整数判定関数
//          KB入力値が整数であれば、真を返却する
//          整数でなければ、偽を返す
///////////////////////////////////////////////////////////////////////////////////
int IntdigitChk( const char *p )
{
    // 空文入力チェック
    while( *p == '\n'){
        return 0;
    }
    // 最初に スペースと '+','−'の符号をチェック
    while ( *p == ' ' || *p == '-' || *p == '+' ){
        p++;
    }

    while (*p != '\n' && *p != '\0'){
        if (!isdigit((int)*p++)){//isdigitの型は(int)
            return 0;
        }
    }

    return 1; 
}
///////////////////////////////////////////////////////////////////////////////////
//          カンマ編集処理
///////////////////////////////////////////////////////////////////////////////////
void CommaEdit(char *s)
{
    int count;
    int i;
    int LEN;
    LEN = (int) strlen(s);  printf("mojisuu = %d\n",LEN);
    count = LEN % 3;
    
    if  (count == 0){
        count = 3;
    }
    
    i = 0;
    for (;;) {
        putchar(s[i]); /* 数値を一文字ずつ表示する */
        i++;
    
        if (i == LEN){
            break;
        }

        count--;
            
        if (count == 0) {
            putchar(',');
            count = 3;
        }
    }
    printf("\n");

    return;
}
/*** by あきき ***/




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:いくら調べても分からないカンマ編集! 3866 REE 2005/06/02 13:17:58
<子記事> Re:いくら調べても分からないカンマ編集! 3888 かずま 2005/06/03 10:12:16


No.3866

Re:いくら調べても分からないカンマ編集!
投稿者---REE(2005/06/02 13:17:58)


>例えば、-,123,45などと表示されます。一体どこが悪いのでしょうか?

あなたの期待とどう違うのですか?



この投稿にコメントする

削除パスワード

No.3867

Re:いくら調べても分からないカンマ編集!
投稿者---あきき(2005/06/02 13:45:30)


>>例えば、-,123,45などと表示されます。一体どこが悪いのでしょうか?
>
>あなたの期待とどう違うのですか?

例えば、
1 -,123,45の様な表記自体がおかしくて、-12,345と表記したいのです。
2 -000011344と入力した時、-,000,011,344 とではなく、-11,344と編集しなおしたいのです。(ゼロサプレスっていうのですか)
3 空文はエラーメッセージ出力する
4 スペースを含む入力値はエラーメッセージ出力する




この投稿にコメントする

削除パスワード

No.3868

Re:いくら調べても分からないカンマ編集!
投稿者---もぐりん(2005/06/02 14:16:25)


>例えば、
>1 -,123,45の様な表記自体がおかしくて、-12,345と表記したいのです。

数字の桁数は求められますよね?
配列に格納する場合は1の位から順に格納していけば、桁数に応じて3桁毎にカンマを入れていくだけでは?

>2 -000011344と入力した時、-,000,011,344 とではなく、-11,344と編集しなおしたいのです。(ゼロサプレスっていうのですか)

これも文字列で取得するのではなくて、数字で取得すれば解決できると思います。


>3 空文はエラーメッセージ出力する

文字列の長さが0であれば、エラーメッセージ出力するでいいでしょう。

>4 スペースを含む入力値はエラーメッセージ出力する
>

1文字単位で判定すればいいのでは?




この投稿にコメントする

削除パスワード

No.3869

Re:いくら調べても分からないカンマ編集!
投稿者---円零(2005/06/02 14:53:19)


カンマの位置がずれるのはLENが改行を含む文字数だからです。

また、符号の直後にカンマが来るのも意図に反しているでしょうから、
符号を書き出す処理をループを開始する前にやっておいた方がいいでしょう。

ゼロを読み飛ばすのは単にそうした処理を追加するだけです。
なお、現在のIntdigitChkは++みたいに符号が連続したりとか、
スペースだけの文字列を通してしまいますから、
・空入力(先頭が改行)をはじく
・スペースを読み飛ばす
・符号を読み取る
・0を読み飛ばす
・末尾まで数字のみであることを確認する
と言う手順でチェックすると良いのではないでしょうか。


この投稿にコメントする

削除パスワード

No.3871

Re:いくら調べても分からないカンマ編集!
投稿者---円零(2005/06/02 15:00:00)


>・0を読み飛ばす

あ、すみません、間違えました。
IntdigitChkは文字列をいじらない関数でしたね。
CommaEditで、
・まず符号を読み取って書き出す
・符号、先頭のゼロ、改行を取り去った文字列を作る
・その文字列にたいして今の処理を適用する
とすれば良いでしょう。


この投稿にコメントする

削除パスワード

No.3888

Re:いくら調べても分からないカンマ編集!
投稿者---かずま(2005/06/03 10:12:16)


> 例えば、-,123,45などと表示されます。一体どこが悪いのでしょうか?

どこが悪いのかに対する指摘は他の方がされているので、私は別解を示します。
#include <stdio.h>

void put(unsigned int n)
{
    n >= 1000 ? put(n/1000), printf(",%03u", n%1000) : printf("%u", n);
}

void comma_print(int n)
{
    n < 0 ? putchar('-'), put(-n) : put(n), putchar('\n');
}

int main(void)
{
    int n, d;  char c, buf[256];

    printf("整数を入力してください : \n" "Input : ");
    if (fgets(buf,sizeof buf, stdin)
            && sscanf(buf, " %n%d%c", &n, &d, &c)==2 && n==0 && c=='\n')
        comma_print(d);
    else
        puts("整数を入力しろといってるだろが!ボケ");
    return 0;
}



この投稿にコメントする

削除パスワード

No.3897

Re:いくら調べても分からないカンマ編集!
投稿者---あきき(2005/06/03 23:54:21)


やっぱり、ssanfを使用しないといけなかったんですね。ですが、説明書を読んでも、何をするライブラリーなのか?から始めなければなりませんから、
    if (fgets(buf,sizeof buf, stdin)
            && sscanf(buf, " %n%d%c", &n, &d, &c)==2 && n==0 && c=='\n')

での条件が分からないので、変数の意味と、sscanf(buf, " %n%d%c", &n, &d, &c)==2 の意味を教えて頂けないでしょうか。
それと、条件演算子を用いてたと思うのですが、例えば、putchar('-')と put(-n)の間にカンマを使用する意味は条件演算子をもとに、連続処理を行う事なんでしょうか?

void comma_print(int n)
{
n < 0 ? putchar('-'), put(-n) : put(n), putchar('\n');
}



この投稿にコメントする

削除パスワード

No.3898

Re:いくら調べても分からないカンマ編集!
投稿者---Ban(2005/06/04 00:27:48)


>やっぱり、ssanfを使用しないといけなかったんですね。

いけないということはありません。実現手段は一つではありません。

>ですが、説明書を読んでも、何をするライブラリーなのか?
>から始めなければなりませんから、

そこからはじめるべきだと思います。それが勉強です。

scanf は、自分で調べていかないと多分理解しきれないと思います。
結構とっつきにくい仕様だと思いますので、
こちらのサイトの解説などを参照しながら調べてみた方がいいと思います。

>putchar('-')と put(-n)の間にカンマを使用する意味は
>条件演算子をもとに、連続処理を行う事なんでしょうか?

結果としてはそうですが、三項演算子とカンマは直接的関係ありません。
C 言語におけるカンマの挙動や演算子の優先順位について
調べてみてください。


この投稿にコメントする

削除パスワード

No.3908

Re:いくら調べても分からないカンマ編集!
投稿者---かずま(2005/06/04 21:51:28)


> やっぱり、ssanfを使用しないといけなかったんですね。
そんなことはありません。やり方はいろいろあります。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

    int d;  char buf[256], *p;

    if (fgets(buf,sizeof buf, stdin) && !isspace((unsigned char)buf[0])
            && (d = strtol(buf, &p, 10), *p == '\n'))


>   if (fgets(buf,sizeof buf, stdin)
>           && sscanf(buf, " %n%d%c", &n, &d, &c)==2 && n==0 && c=='\n')
>
> での条件が分からないので、変数の意味と、
> sscanf(buf, " %n%d%c", &n, &d, &c)==2 の意味を教えて頂けないでしょうか。

scanf の仕様をマニュアルで確認されましたか?

  " "   -- 空白(スペースやタブなど)を読み飛ばす。
  "%n"  -- そこまでに読み込んだ文字数を取得する。
  "%d"  -- 符号付きの10進整数を読み込んで変換する。
  "%c"  -- 1文字読み込む。

  n には整数の直前の空白の文字数が入ります。
  d には整数の値が入ります。
  c には整数の直後の文字が入ります。

sscanf は、変換した項目数を返しますが、%n については変換項目に数えません。
だから、%d と %c の 2 が返れば sscanf は成功です。
スペースを含む入力をエラーにしなければならないので、n==0 && c=='\n' の
チェックが必要です。

整数の前後のスペースをエラーにしないのであれば、

   if (fgets(buf, sizeof buf, stdin) && sscanf(buf, "%d %c", &d, &c)==1)

で十分です。


> void comma_print(int n)
> {
> n < 0 ? putchar('-'), put(-n) : put(n), putchar('\n');
> }

字下げされていません。注意してください。
条件演算子は使用しないで次のように書くのが普通です。

void put(unsigned int n)
{
    if (n >= 1000) {
        put(n/1000);
        printf(",%03u", n%1000);
    } else
        printf("%u", n);
}

void comma_print(int n)
{
    if (n < 0) {
        putchar('-');
        put(-n);
    } else
        put(n);
    putchar('\n');
}

では、なぜ私がそう書かないかというと、質問が学校の課題として出題された
場合もあるわけで、そのまま提出できるような答えを書いてしまうのを避けて
いるからです。コメントをつけなかったり、変数名を単純なものにしたり、
1行にたくさんの処理を詰め込んだりして、そのまま提出すると先生が「これは
なんだ!」というような書き方をわざとしています。



この投稿にコメントする

削除パスワード

No.3909

Re:いくら調べても分からないカンマ編集!
投稿者---あきき(2005/06/05 01:13:02)


かずまさん、無事解決しました。sscanf関数も他のサイトで調べていたのですが、かずまさんの説明が一番分かりやすかったです。また、再帰関数を使用していたのにはとても驚きました。
入力と同時にデータチェックをするには「fgets」と「sscanf」をセットで覚えておけばいいですね。ありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity