"one","two","three","four","five","six","seven","eight","nine","ten" のポインタ配列の文字列を、ASCIIコード順に並べ変えようと思ったのですが、
もうどこが間違っているかさえわからないぐらいになってしまいました。
まだまだはじめたばかりなもので、わからないことだらけなんで、
できるだけわかりやすい説明おねがいします。
関数の引数に問題があるのじゃないかと思ったのですが、
何かいいアドバイスありましたら、お願いします。
#include <stdio.h>
/* 関数のプロトタイプ宣言 */
int strmp(char *,char *);
void cpy(char *,char *);
int main (void)
{
/* ポインタ配列の定義 */
char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"};
/* ポインタのポインタの定義 */
char **pp=x;
char k[100];
char *p=k;
int i,t,a,b,c,d;
a=0;
/* ポインタ配列を自作関数を使って、ASCIIコードの大きいほうからに並び替える */
for(i=0;i<9;i++)
{
for(t=1;t<10;t++)
{
a=strmp(*(pp+i),*(pp+t));
if(a<0)
{
cpy(p,*(pp+i) );
cpy(*(pp+i),*(pp+t) );
cpy(*(pp+t),p);
}
}
}
for(i=0;i<10;i++)
{
printf("%s ,",x[i]);
}
printf("\n");
return 0;
}
/* 文字の比較をする関数 */
int strmp(char *x,char *y)
{
int i;
for(i=0;*(x+i)==*(y+i);i++)
{
if( *(x+i)=='\0')
{
return 0;
}
}
return *(x+i)-*(y+i);
}
/* 文字をコピーする関数 */
void cpy(char *a,char *b)
{
int i;
for(i=0;*(b+i)!='\0';i++)
{
*(a+i)=*(b+i);
}
*(a+i)='\0';
}
No.1
- 回答日時:
並び替える時に文字をコピーする必要はありません。
(二次元配列の時はコピーが必要です)
char *x[2]={"one","twoooooooooo"};
char *t;
/* x[0]とx[1]を交換する */
t = x[0];
x[0] = x[1];
x[1] = t;
/* 交換終了 */
strmp関数は、ぱっと見うまく出来ているように見えます。
あとは、バブルソートで交換していく部分を作りこんでいけば動くと思います。
No.2
- 回答日時:
> "one","two","three","four","five","six","seven","eight","nine","ten" のポインタ配列
についてソートしたいのですから、
> char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"};
こうではなく
char *x[10]={"one","two","three","four","five","six","seven","eight","nine","ten"};
と定義して、プログラムが正しく動くようにしなければなりませんね。
No.3
- 回答日時:
複雑に考え過ぎのようです。
違うやり方で処理してます。#include <stdio.h>
/* 関数のプロトタイプ宣言 */
int strmp(char *,char *);
void cpy(char *,char *);
int main (void)
{
/* ポインタ配列の定義 */
char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"};
//
// このままだとセグメント違反になるので、この配列は固定にしてインデックス
// のソートをする。オリジナル方式でやる場合、二次元配列に移し替えてから最初のfor分を実行する。
//
// 以下の p[ 10 ]がインデックスの配列。
int p[ 10 ];
char k[100]; // これは不要
int i,t,a,b,c,d;
a=0;
// インデックスを初期化する
for(i=0;i<10;i++){
p[ i ] = i;
}
/* ポインタ配列を自作関数を使って、ASCIIコードの大きいほうからに並び替える */
for(i=0;i<9;i++){
// 初期値は1固定だと期待した結果にはならない。 i+1 です。
for(t=i+1;t<10;t++){
// 大小の判定
a = strmp( x[ p[ i ] ], x[ p[ t ] ] );
if( a < 0 ){
// インデックスの入れ替え
b = p[ i ];
p[ i ] = p[ t ];
p[ t ] = b;
}
}
}
for(i=0;i<10;i++){
// 並び替えられたインデックスで、元もとの文字列のポインタの
// 配列を指す。
printf("%s ,", x[ p[i] ]);
}
printf("\n");
return 0;
}
/* 文字の比較をする関数 */
int strmp(char *x,char *y)
{
int i;
// ポインタのみで実行するほうが処理は速い。
while( *x != '\0' ){
if( *x++ < *y++ ){
return -1;
}
else{
return 1;
}
}
return 0;
}
/* 文字をコピーする関数 */
void cpy(char *a,char *b)
{
// ポインタのみで実行するほうが処理は速い。
while( *b != '\0' ){
*a++ = *b++;
}
*a ='\0';
}
わかりやすい説明ありがとうございました。
ポインタ配列とポインタのポインタだけでどうにかやろうと思ったんですが
どうやら無理があったようですね。
もっと広い視野でみないとだめですね
No.4ベストアンサー
- 回答日時:
★ポインタを使いこなしていませんね。
・あまり、ポインタを使いすぎるとわけが分からなくなりますよ。
>a = strmp( *(pp+i), *(pp+t) );
の『*(pp+i)』や『*(pp+t)』の部分は pp[i]、pp[t] でも同じにアクセスできますので
配列と同じように表記した方が私は見やすいと思います。もしも、ポインタを使うなら
『*(pp+i)』で参照するのがこだわりがあってのことなら pp[i] にしなくても良いが…。
・あと並びを入れ替えるときに文字列の中身を入れ替えています。
文字列のポインタだけを、ポインタ同士で入れ替えれば簡単ですよ。
●間違い
cpy( p,*(pp+i) );
cpy( *(pp+i), *(pp+t) );
cpy( *(pp+t), p );
●正しい
char *tp[ 1 ]; ←これを宣言(temp の tp です)
tp[ 0 ] = pp[ i ];
pp[ i ] = pp[ t ];
pp[ t ] = tp[ 0 ];
となります。cpy() 関数は文字列の内容をコピーするようですが、ポインタ配列の中身を
書き換えたいのですか?文字列定数を書き換えようとするとエラーになりませんか?
もしも、文字列の内容をアルファベット順に書き換えたい場合は、
char s0[] = "oneee";
char s1[] = "twooo";
char s2[] = "three";
char s3[] = "fourr";
char s4[] = "fivee";
char s5[] = "sixxx";
char s6[] = "seven";
char s7[] = "eight";
char s8[] = "ninee";
char s9[] = "tennn";
char *x[10]={ s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 };
と定義しないといけません。
この方法ならば、cpy() 関数で中身をコピーして入れ替えできます。そういう考えでしたら
上の『間違い』が間違いではなくて本当に正しくなります。どっち?
参考ソース:
int main( void )
{
char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn" };
char *p[1]; ←宣言
int i, t, cmp;
/* バブルソート(降順) */
for ( i = 0 ; i < (10 - 1) ; i++ ){
for ( t = i + 1 ; t < 10 ; t++ ){ ←t には i+1 を代入しないとマズイ!
cmp = strmp( x[i], x[t] );
if ( cmp < 0 ){
p[ 0 ] = x[ i ];
x[ i ] = x[ t ];
x[ t ] = p[ 0 ];
}
}
}
/* ソート結果表示 */
for ( i = 0 ; i < 10 ; i++ ){
printf( "%s, ", x[i] );
}
printf( "\n" );
return 0;
}
/* 文字列の比較 */
int strmp( const char *x, const char *y )
{
while ( *x == *y ){
if ( *x == '\0' ){
return 0;
}
x++;
y++;
}
return (*x - *y);
}
その他:
・http://www.codereading.com/algo_and_ds/algo/bubb …→『バブルソート』
・http://oshiete1.goo.ne.jp/qa2577202.html→『ポインタで詰まりました;』
・上記も参考に!
参考URL:http://www.codereading.com/algo_and_ds/algo/bubb …
char s0[] = "oneee";
char s1[] = "twooo";
char s2[] = "three";
char s3[] = "fourr";
char s4[] = "fivee";
char s5[] = "sixxx";
char s6[] = "seven";
char s7[] = "eight";
char s8[] = "ninee";
char s9[] = "tennn";
char *x[10]={ s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 };
とやった結果どうにかできました。
自分としてはどうにかポインタ配列とポインタのポインタでやってみようと思っていたので、こんなおかしな物になってしまいました。
私のそのあたりの説明が不足していたようで、申し訳ありませんでした。
とてもわかりやすい説明ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
文字列内の数字削除
-
C言語のintとcharの違いってな...
-
文字列str内の全ての数字を...
-
C言語で文字列をかえす正しい書...
-
SetWindowTextについて。
-
char*を初期化したいのですが
-
構造体が戻り値の関数について...
-
strcat関数を自作したいです
-
CStringからchar*への型変換に...
-
C言語を用いた環境変数の作成/...
-
C言語でポインターで詰まってい...
-
C言語にて構造体のメンバがNULL...
-
char型にint型の数値を代入する。
-
new charとnew char[N]の違いは?
-
char 文字列型 の表現範囲が-12...
-
C言語において、以下の条件で...
-
p = (char **)*p の意味
-
文字の代入とコピーについて
-
ポインタを使用 [数字列を数値...
-
文字列の途中から途中までを抽出
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
strcat関数を自作したいです
-
fstream型オブジェクトを関数の...
-
new charとnew char[N]の違いは?
-
DWORDとcharの変換
-
文字列の途中から途中までを抽出
-
char 文字列型 の表現範囲が-12...
-
const char* s1とただのchar s1...
-
wsprintf( ポインタ , "%d" , "...
-
c言語でポインタ変数を用いた配...
-
char型にint型の数値を代入する。
-
C言語で文字列をかえす正しい書...
-
C++17で、unsigned char * 配列...
-
共用体について
-
エクセルのMID関数は、C言語では?
おすすめ情報