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

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

 詳しくはこちら



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

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


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

No.18776

ポインタを使った文字列変換
投稿者---sincos(2004/12/17 01:38:18)


こんばんわ。どうしてもわからない所があって質問に来ました。

現在、ポインタを使用した文字列変換(具体的には小文字を大文字変換)のプログラムを作っているのですが、どうしてもエラーが消えません。

ソースはコレなのですが

#include <stdio.h>

void upper(char *p_data); 

void upper(char *p_data)
{
    int x; 

    for (x = 0; x < 5; x++) {
        if (p_data[x] > 'a' && p_data[x] < 'z') {
            p_data[x] = p_data[x] - 32; 
        }

    }
}


int main(void)
{
    char str[] = "apple"; 

    upper(p_data); 

    printf("str = \"%s\"\n", p_data); 
}



*p_dataとstrを入れ替えたりする場所や方法がどうやっても思い浮かびません。"apple"を"APPLE"に変換したいのですが……。
どなたかご教授の程、宜しくお願いいたします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ポインタを使った文字列変換 18777 BB 2004/12/17 01:54:39
<子記事> Re:ポインタを使った文字列変換 18779 Masuo 2004/12/17 10:02:51


No.18777

Re:ポインタを使った文字列変換
投稿者---BB(2004/12/17 01:54:39)


>どうしてもエラーが消えません。
エラーが出るときはちゃんとどんなエラーが出てるかを書いた方がいいですよ。

>upper(p_data);
>printf("str = \"%s\"\n", p_data);
この二つは
upper(str);
printf("str = \"%s\"\n", str);
ではないですか?


この投稿にコメントする

削除パスワード

No.18779

Re:ポインタを使った文字列変換
投稿者---Masuo(2004/12/17 10:02:51)


>どうしてもエラーが消えません。

 main関数内の upper(p_data); の部分でエラーだと思いますが、
upper関数の仮引数 p_data は upper関数のブロックスコープを
有するため、 main関数からは見ることができません。

 また、main関数の戻り値を int 型で指定しているにも関わらず、
戻り値を返していないので、警告もでると思います。


ソースに関しては、以下のもので動作すると思います。

#include<stdio.h>



/***** プロトタイプ宣言 *****/
void upper( char* p_Str );



int main( void )
{
    char str[] = "apple";


    /*** 大文字へ変換 ***/
    upper( str );      // 文字列 str のポインタを渡す


    /*** 文字列を出力 ***/
    printf( "str = \"%s\"\n", str );


    return 0;
}



void upper( char* p_Str )
{
    int i = 0;    // ループ用


    /***** 変換ループ *****/
    while( *(p_Str + i) )                           // 文字列内の \0 になるまで変換を継続
    {
        /*** ポインタが指す文字が小文字英数か ***/
        if( *(p_Str + i) >= 'a' && *(p_Str + i) <= 'z' )
            *(p_Str + i) = 'A' + *(p_Str + i) -'a';   // 小文字英数なら変換
        i++;                                                // 次の文字
    }
}


ポインタに関してはC言語の壁とも言われており、難しいと
考えられていますが、そのように感じさせるのは書籍や学習方法に
問題があるためだと思います。ポインタは簡単なものなので、さらに
学習をして基礎を固めた方が良いと思います。


この投稿にコメントする

削除パスワード

No.18794

Re:ポインタを使った文字列変換
投稿者---sincos(2004/12/17 23:53:57)


なるほど……参考になります。
自分の至らなさがわかります。
これから少しずつでもいいので学んでいきます。

もう一つ質問なのですが、10文字以内(10文字以降は削除)の文字列を比べて同じならばgood、同じで無いならばbadを返すプログラムを作成しているのですが、上記のプログラムを参考にさせていただいたものの完成できません。
どうにも警告が出てしまいます……。
下にソースを張ります。


#include<stdio.h>
#include <string.h>

/***** プロトタイプ宣言 *****/
void get_string( char* p_str );

int main( void )
{
    char str1[11]; 
    char str2[11]; 

 
    get_string( str1 );      // 文字列 str1 のポインタを渡す
    get_string( str2 );      // 文字列 str2 のポインタを渡す



    if (!strcmp(str1, str2)) {        /*a=bならば文字[good]を返す*/
        printf("good\n"); 
    }

    else                                /*a=bでないのならば文字[bad]を返す*/
        printf("bad\n"); 
    return 0;
}



void get_string( char* p_str )
{
    printf("文字列str1 : "); 
    fgets(*(p_str), 11, stdin); 
    fflush( stdin ); 
    printf("文字列str2 : "); 
    fgets(*(p_str), 11, stdin); 
    fflush( stdin ); 
}


ユーザ定義関数はvoid get_string(char *p_str)で固定したいのですが、どうすればいいのでしょう?
連投になってしまってすいません。教えていただけると幸いです。


この投稿にコメントする

削除パスワード

No.18795

Re:ポインタを使った文字列変換
投稿者---monkey(2004/12/18 08:17:59)


警告でなくてエラーですね。

【掲示板ご利用上の注意】
※環境(OSとコンパイラ)や症状は具体的に詳しく!

BBさんも既に指摘されていますが、コンパイルエラーの場合はコンパイルエラーをそのまま書くべきです。
また、環境も必ず書いて下さい(コンパイラによってエラーメッセージの出し方が異なるため)。
このような場で有効な回答を得たければ、利用上のルールに従うこと、人の話を聞くことを先に学んで下さい。

エラーの原因は、fgets関数の第1引数に渡している値の型が間違っているためです。
fgets関数のプロトタイプを確認するとともに、ポインタに対する*演算子の働きをよく勉強してください。

get_string関数の中で2回fgets関数を呼んでいますが、2回とも同じ文字列(p_strが指す領域)に書き込もうとしています。
ここのエラーがなくなったとしても、得られる文字列は2回目に読み込んだものだけになりますが、それは意図した処理なのでしょうか?



この投稿にコメントする

削除パスワード

No.18800

Re:ポインタを使った文字列変換
投稿者---sincos(2004/12/19 06:57:17)


申し訳ございません。
どうにもコンパイラの環境がわからなかったので……。

使用OSはXP(SP2)、コンパイラはWin32 Debugと表示されます。
しかし、エラーは出ずに警告だけ……。内容は2つのfgetsの部分に
「'function' :間接参照のレベルが 'char *' と 'char ' で異なっています。」
「'fgets' : の型が 1 の仮引数および実引数と異なります。」
と出てきて、どうにも消せません。

>get_string関数の中で2回fgets関数を呼んでいますが、2回とも同じ文字列(p_strが指す領域)に書き込もうとしています。
>ここのエラーがなくなったとしても、得られる文字列は2回目に読み込んだものだけになりますが、それは意図した処理なのでしょうか?

プロトタイプ宣言で*p_str1つしか呼び出さないようにしていますので、2つの配列をどうすればいいのかよく分かっていないのです……。


この投稿にコメントする

削除パスワード

No.18801

Re:ポインタを使った文字列変換
投稿者---monkey(2004/12/19 08:13:20)


> どうにもコンパイラの環境がわからなかったので……。

最低限、お使いのコンパイラの名前とバージョンくらいはお書き下さい。

> 使用OSはXP(SP2)、コンパイラはWin32 Debugと表示されます。
> しかし、エラーは出ずに警告だけ……。内容は2つのfgetsの部分に
> 「'function' :間接参照のレベルが 'char *' と 'char ' で異なっています。」
> 「'fgets' : の型が 1 の仮引数および実引数と異なります。」

メッセージの内容等からみて、コンパイラはMicrosoft VisualC++(バージョンは不明)をお使いのようですね。
メッセージは、fgets関数に渡している実引数の型と仮引数の型が違いますよ、と言っています。
fgets関数の第1引数には、読み込んだ文字列の格納先のメモリ領域(char型配列)の先頭を指すポインタを渡します。

void get_string( char* p_str );

この仮引数"p_str"はポインタ型ですから、これをそのままfgets関数の第1引数に渡せば良いです。
ポインタ変数の頭に"*演算子"をつけると、そのポインタが指すデータの値をとりだすという意味になります。
ポインタの詳細については、大事なところですので参考書等でご確認ください。

# エラーにせずに警告で済ませているのは、C++のコンパイラとしては甘いような気がしますが、、、
# Borland C++ Compiler ver.5.5では、しっかりエラーにしてくれました。


> プロトタイプ宣言で*p_str1つしか呼び出さないようにしていますので、
> 2つの配列をどうすればいいのかよく分かっていないのです……。

get_string関数1回の呼び出しで2個の文字列を読み込みたいなら、引数を2個にする。

void get_string( char* p_str1, char* p_str2 )
{
    printf("文字列str1 : "); 
    fgets( p_str1, 11, stdin ); 
    fflush( stdin ); 
    printf("文字列str2 : "); 
    fgets( p_str2, 11, stdin ); 
    fflush( stdin ); 
}

int main()
{
    ...

    get_string( str1, str2 );

    ...
}

あるいは、fgets関数呼び出しを1回にして、main関数から2回get_string関数を呼ぶ。

void get_string( char* p_str )
{
    fgets( p_str, 11, stdin );
    fflush( stdin );
}

int main()
{
    ...

    printf("文字列str1 : "); 
    get_string( str1 ); 
    printf("文字列str2 : "); 
    get_string( str2 );

    ...
}

以上。



この投稿にコメントする

削除パスワード

No.18804

Re:ポインタを使った文字列変換
投稿者---BB(2004/12/19 11:31:29)


>fflush(stdin);
fflushは出力ストリームにしか使えません。C FAQにも書かれてます。

ttp://www.kouno.jp/home/c_faq/c12.html#26

stdinを指定した場合の動作は未定義なので使わない方がいいかと。
どちらにしろ、わざわざ使う必要はないと思います。


この投稿にコメントする

削除パスワード

No.18805

Re:ポインタを使った文字列変換
投稿者---monkey(2004/12/19 11:48:57)


>>fflush(stdin);
>fflushは出力ストリームにしか使えません。C FAQにも書かれてます。

うっかりそのままにしてしまいました。ご指摘感謝いたします。


この投稿にコメントする

削除パスワード

No.18815

Re:ポインタを使った文字列変換
投稿者---sincos(2004/12/20 00:57:08)


本当にすいませんでした。よく読んでいなかったせいで不快にさせてしまい申し訳ありません。
それでも教えてくださって感謝しております。

よくよく考えたら処理は1つだけでいいんですよね……。変に固執しすぎていました。
基礎を学ぶとと共に柔軟性も持っていきたいですね。

monkeyさん、BBさん、Masuoさんありがとうございました。


この投稿にコメントする

削除パスワード

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