10秒目をつむったら…

下記コードは順番は逆になりますが、中身がソートされません。
int等実数では成功しますが、文字列ソートに対応したいのです。
よろしくお願いします。

typedef struct {
char tel[16];
char tel1[202];
} TelData;

int cmp( const void *p, const void *q ) {
return (*(TelData**)q)->tel - (*(TelData**)p)->tel;
}

A 回答 (5件)

実データをソートしてしまいたいんですね。



int a, b; //これを入れ替える
int t = a; a = b; b = t; とするでしょ?

これと同じことですよ。
TEL_DATA a, b;
TEL_DATA t;
strncpy(t.tel, a.tel, 12); strncpy(a.tel. b.tel, 12); strncpy(b.tel, t.tel, 12);
strncpy(t.tel1, a.tel1, 202); strncpy(a.tel1, b.tel1, 202); strncpy(b.tel1, t.tel1, 202);


この部分を関数化するよね int swap(int &a, int &b); とかにして
void swap(int *a, int *b)
{
int t = *a; *a = *b; *b = t;
}

なのでこういうのがいる
void swap(TEL_DATA *a, TEL_DATA *b)
{
TEL_DATA t;
strncpy(t.tel, a->tel, 12); strncpy(a->tel. b->tel, 12); strncpy(b->tel, t.tel, 12);
strncpy(t.tel1, a->tel1, 202); strncpy(a.tel1, b->tel1, 202); strncpy(b.tel1, t->tel1, 202);
...
 要素数が多いとかなり力技になるから・・

#include <string.h>
memcpy(&t, a, sizeof(TEL_DATA));
memcpy(a, b, sizeof(TEL_DATA));
memcpy(b, &t, sizeof(TEL_DATA));
全体一気にコピーしてもいいね
    • good
    • 1
この回答へのお礼

わかりました、テンポラリーを噛ます訳ですね
それでメモリーコピーで一気にですか
これで、通常のソートプロシージャーが使えポインターを理解していなくても解決しそうです。
ただ100万件とか大量のデーターは時間がかかりそうです!!

ちなみにアセンブラだとEDI,ESIインデックスレジを使えば済むはなしですが、
cだと理解できません。

ありがとうございました。

お礼日時:2018/05/29 10:57

いや、同じですよ。

アセンブラでイメージあるならそのままのように書ける。
実ソートしないってことは先に書いたようにインデックス作るって事ですよ。
こう言うものは実ソートしないね。

あとソートアルゴリズムになるからこのコードを呼ぶのは実際に「それ」が必要な時でしよ?バブルソートのように毎回見つかった時に実ソートしてたら、、orzだよね。つまりは一時的にせよインデックスがいる。なら、そのインデックス使えば実ソートはないんだから早いでしょう?
    • good
    • 0
この回答へのお礼

メモリーの移動を伴わない分、実ソートが早いのですね。勉強します。
ありがとうございました。

お礼日時:2018/05/29 11:45

比較関数 cmp にて、


1バイト整数(char)の大小比較ではなく、
文字列(char[])の辞書順比較をするならば

return -(strncmp(キャストしたp->tel, キャストしたq->tel, 16);

参考
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/ …
    • good
    • 0
この回答へのお礼

Ogre7077さん
ありがとうございました。
解決しました。

お礼日時:2018/05/29 11:22

struct TEL_DATA


{
char tel[16];
char tel1[202];
};

class TEL_MAN
{
TEL_DATA tel_list[100];
int tel_index[100];
int tel_num;

public:
TEL_MAN();
int sort();
TEL_DATA * operator[] (int a); // これでソートデータを得たらいいとおもう
};


{
TEL_MAN telm;
...
}


ポインターがわからないというのはよく聞くけど、アセンブラ使うならメモリーアクセスにレジスターにアドレスいれて参照するよね?これポインターだろ。
そもそも、このポインターが指すメモリー番地は単なる (intサイズ) のデータを参照できるだけであって、文字なのか、文字列なのか、数値なのか、はたまた浮動小数フォーマットデータなのかなんて、使う側しかわからないよね。

キャスト(キャスティング)は、概念的な適当な意味をもたせてるだけで実際のメモリーの中身がどうキャストしようが変化するわけでもないってこと。

ただ、代入時にコンパイラーに対してのヒントを示せるから、char c = (int)b というのはちょっとまずいんじゃない?って警告判定は出せるけれど、実際にアセンブラーレベルでは普通にしていることだからさ。 これでいいんだよと char c = (char) ((int)b)) をとコンパイラに「知っててやってるんですよ」って警告を出させないように余計なキャストするってところがあるわけ。

これ、プロセッサレベルのコードを意識できない人には、かなりの難解モードとなるんですよね。

アセンブラで書いたことがあるというのだから、単なるメモリーを私たちは意味をもたせているという概念が見えてきたら、「あらら、Cってよく考えてるよね」ってわかってくると思うよ。

兎にも角にもアセンブラで記載できる事、プロセッサ命令コードを記載できる表記がCには備わっているってことでみたら、難しいと思うことが霧が晴れるように見えてくるはず・・

頑張って・・
    • good
    • 0
この回答へのお礼

丁寧な回答ありがとうございます。
お示しいただいたコードは今後勉強します、私には難しいです。
アセンブラは命令数も少なく単純で判りやすかったのですが!!!

今回は一般的な、ポインター渡しでないソートコードを使い文字列ソートをします。
2カラム目をクリックしたら1カラムのデータと2カラム目のデーターをスワップして
ソート後再スワップします。

お示しのコードは、まだ検証していませんが・・・ありがとうございました。

お礼日時:2018/05/29 10:07

ナンジャコリャ?



あのさ、C/C++はアセンブラに変わるものとして設計されたわけ。
なのでプロセッサ命令を知ってアセンブラを使ったことがあるなら、Cの記述はすんなりと納得できるものばかり。

ポインターにしても特別なものでもなく、キャストも便宜的なもの。

貴方のコードは基本が外れてる。

TelData に operator - () が無いのに TelData - TelData なんて、どんな結果を期待してる?
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
アセンブラーのみで一本のゲームを作ったことはありますが・・・
私は、基本も学ばず、ぶっつけ本番でプログラムしています。
キャストが理解できません、
解決策をどうかご教授ください。

お礼日時:2018/05/29 08:45

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