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

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

 詳しくはこちら



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

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


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

No.19377

long → 10進文字列変換
投稿者---ニック(2005/01/22 00:57:56)


はじめまして、ニックといいます。

C言語に関してはかなり初心者です。ポインタの部分で
かなりてこづりました。

質問をしますが、冷やかしや突っ込みなどはしないでください。
質問をする側の言うことではないような気がしますがお願いし
ます。

下記のプログラムは、整数を文字列に変換するものです。

質問の内容はコメントの部分に書いてあります。

ご指導ください。

/*
    long → 10進文字列変換
    引き数 long lval;   変換数値
        char *str;  10進文字列
    返り値 str
*/

char *ltoa(long lval,   char *str)
{
    unsigned long ulval;/*符号無整数*/
    char *p1 = str;
    char *p2;

    if(lval < 0){      /*符号チェック*/
        ulval = -lval;/*符号チェックでマイナスの場合なので符号を消す*/

        *p1++ = '-';/*ここが何をやっているのかがわかりません
                    *p1++ということはp1の内容だからそこに
                            マイナスの符号が入る?*/
    } else
        ulval = lval;/*ここは+の場合だからそのまま入れる?*/

    p2 = p1;      /*10進文字列 格納アドレスセット*/

             /*先ほど'-'がいれられたp1がどのように反映されているかがわかりません。*/

    do {
        *p2++ = (char)((ulval % 10)+'0');/*ここは多分%10で下桁を取り出して+'0'でAscci
                                に変換?*/
            /*余りAscii変換*/
    }while((ulval /= 10) != 0);/*ここの条件の部分がわかりません?*/

    *p2 = '\0';/*最後にNULL文字を入れる*/

    while(p1 < --p2){/*文字列逆順変換*/
        char ch; /*LSB→MSBをMSB→LSBに変換*/

        ch    = *p1;/*ここらへんもなんとなくわかるんですがp1とp2にどのように文字列が
                    入っているのかがあいまいなのでちょっとわかりません*/
        *p1++ = *p2;
        *p2   = ch;
    }
    return(str);
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:long → 10進文字列変換 19383 RAPT 2005/01/22 03:19:53


No.19383

Re:long → 10進文字列変換
投稿者---RAPT(2005/01/22 03:19:53)


多分、要所要所でどんな値が変数に入るのかが想像できないから悩んでいるのでしょう。
であれば、その変数の中身を参照してみれば、理解の助けになるでしょう。


> *p1++ = '-';/*ここが何をやっているのかがわかりません
これは、下記の文と同等です。p1の指し示す先に'-'をセットし、p1を1進めます。
*p1 = '-';
++p1;


> /*先ほど'-'がいれられたp1がどのように反映されているかがわかりません。*/
ここで次の文を記述して中身を確認できます。
printf("p1 = (%s)\n", p1);


> *p2++ = (char)((ulval % 10)+'0');/*ここは多分%10で下桁を取り出して+'0'でAscci
>                                 に変換?*/
はい。
次の簡単なサンプルプログラムを作成し動作を確認してください。
#include <stdio.h>

int main()
{
  unsigned long uval, a, b;
  char c;
  for( uval = 0; uval < 10; ++uval ){
    a = uval % 10;
    b = a + '0';
    c = (char)b;
    printf("i = %d\ta = %u\tb = %c\tc = %c\n", i, a, b, c);
  }
  return 0;
}


> }while((ulval /= 10) != 0);/*ここの条件の部分がわかりません?*/
(ulval /= 10) は 次の文と等価です。
ulval = ulval / 10;
従って、((ulval /= 10) != 0) は、ulval / 10 が 0と等しくない時、
真になり、ループは継続されます。

> ch    = *p1;/*ここらへんもなんとなくわかるんですがp1とp2にどのように文字列が
>               入っているのかがあいまいなのでちょっとわかりません*/
> *p1++ = *p2;
> *p2   = ch;
上記の文の上と下に次の文を記述してください。
printf("入換前:*p1 = %c\t*p2 = %c\n", *p1, *p2);
printf("入換後:*p1 = %c\t*p2 = %c\n", *p1, *p2);

また、上記の文は下記の文と等価です。
ch  = *p1;
*p1 = *p2;
*p2 = ch;
++p1;


■C言語開発をやっている以上、変数の中身をprintf等で確認することは
常々必要となります。分からないのであれば調べてください。
「曖昧です」で終わらせずに、曖昧を解消するよう、努力してください。
# ここでの「努力」とは、printf文をソースコードに埋め込む事です。


■動作確認用サンプルコード(Windows2000sp4/VC++6.0sp6/Console-C)
#include <stdio.h>

char *ltoa(long lval,   char *str)
{
  unsigned long ulval;
  char *p1 = str;
  char *p2 = NULL;
  char ch;

  printf("最初:\tp1=%p\tstr=%p\t lval=%ld\n", p1, str, lval);
  if(lval < 0){
    ulval = -lval;
    *p1 = '-';
    ++p1;
  }else{
    ulval = lval;
  }
  p2 = p1;
  printf("次:\tp1=%p\tp2 =%p\tulval=%u\n", p1, p2, ulval);
  
  do{
    *p2 = (char)((ulval % 10) + '0');
    printf("数値化:\t*p2=%c\t\t", *p2);
    ++p2;
    ulval = ulval / 10;
    printf("-->\tulval=%ld\n", ulval);
  }while( ulval != 0 );
  *p2 = '\0';
  while( p1 < --p2 ){
    printf("置換前:\t*p1=%c\t*p2=%c\tstr=%s\n", *p1, *p2, str);
    ch  = *p1;
    *p1 = *p2;
    *p2 = ch;
    printf("\t-->\t*p1=%c\t*p2=%c\tstr=%s\n", *p1, *p2, str);
    ++p1;
  }
  return str;
}

int main()
{
  long lval = 0;
  char str[100] = {0};
  char *p = NULL;
  printf("lvalは? ");
  scanf("%d", &lval);
  p = ltoa(lval, str);
  printf("lval = %d\np = %s\n", lval, p);
  return 0;
}




この投稿にコメントする

削除パスワード

No.19385

ありがとうございました
投稿者---ニック(2005/01/22 10:31:05)


RAPT 様

ニックです。

私のような物に懇切丁寧にご指導いただきありがとうございました。
RAPT様の今回の書き込みは、私の一生の財産になるものです。

私も前よりも成長することを目標に日々頑張りますので、今後、とも
よろしくお願いします。

まぁ、今回のような書き込みはしませんけど・・・
もう少し自分でははくしてから投稿します。

今回RAPT様のおかげで、その力がつきました。
本当にありがとうございました。



この投稿にコメントする

削除パスワード

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