ポインタ配列を関数で渡す方法について

このQ&Aのポイント
  • ポインタを使用して配列を関数に渡す方法について教えてください。
  • 配列の並び替え処理を関数に渡す際に発生するエラーについて解決方法を教えてください。
  • 適切な方法でポインタ配列を関数に渡す方法を教えてください。
回答を見る
  • ベストアンサー

ポインタのアドレス渡し。。。

ポインタ配列を関数で渡す方法教えてください。 for(cnt1 = 0 ; cnt1 < 5 ;cnt1++) { for(cnt2=cnt1 + 1 ; cnt2 < 5 ;cnt2++) { ret=strcmp(srt[cnt1],str[cnt2]); if(ret>0)    { temp = str[cnt1]; str[cnt1] =str[cnt2]; str[cnt2] = temp; } } この並び替え処理を関数で渡したいのですが、 この処理を関数で以下のようにするとエラーが・・・ void sort(char *pstr,int cnt) { int ct1; int ct2; char *temp; for(ct1 = 0 ; ct1 < cnt-1 ;ct1++) { for(ct2=ct1 + 1 ; ct2 < cnt ; ct2++)   { ret=strcmp(pstr+ct1,pstr+ct2); if(ret>0) { temp = pstr+cnt1; pstr[ct1] = pstr[ct2]; pstr[ct2] = temp; }}} どのように渡せば良いのかわかる方教えていただけませんか??

noname#9404
noname#9404

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

こんばんは。 どのようなエラーが出たのかがわからないので、思ったことを書かせていただきます。 まず、一番下の閉じ中かっこ"}"が1つ足りないです。 それから、 "char *temp;"は"char temp;" "temp = pstr+cnt1;"は"temp = pstr[ct1];" です。 以下に、少し長くなりますが、修正したコードとその使い方、また、BLUEPIXYさんのご回答のコードの使い方を示しておきます。 ご自分の環境で動かしてみてください。 (Windows2000Pro + VC++.NETで確認しました) void sort(char *pstr,int cnt) { int ct1; int ct2; char temp; for(ct1 = 0 ; ct1 < cnt-1 ;ct1++) { for(ct2=ct1 + 1 ; ct2 < cnt ; ct2++) { int ret=strcmp(pstr+ct1,pstr+ct2); if(ret>0) { temp = pstr[ct1]; pstr[ct1] = pstr[ct2]; pstr[ct2] = temp; } } } } void sort2(char **pstr,int cnt){ /*BLUEPIXYさんのご回答のコード(省略します)*/ } int main() { char str[] = "ACBFEDIGH"; printf("ソート1処理前\n"); printf("%s\n", str); sort(str, (int)strlen(str)); printf("ソート1処理後\n"); printf("%s\n", str); printf("\n\n"); int i; char *str2[] = {"XYZ", "RST", "OPQ" }; printf("ソート2処理前\n"); for(i = 0; i < 3; i++) printf("%s\n", str2[i]); sort2(str2, 3); printf("ソート2処理後\n"); for(i = 0; i < 3; i++) printf("%s\n", str2[i]); return 0; }

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

ポインタの配列だから**pstrとして… void sort(char **pstr,int cnt){ int ct1, ct2; int ret; char *temp; for(ct1 = 0 ; ct1 < cnt-1 ;ct1++){ for(ct2=ct1 + 1 ; ct2 < cnt ; ct2++){ ret=strcmp(pstr[ct1],pstr[ct2]); if(ret>0){ temp = pstr[ct1]; pstr[ct1] = pstr[ct2]; pstr[ct2] = temp; } } } }

関連するQ&A

  • 問題です。

    #include <stdio.h> short X1(char *,char *,char *); void X2(char *,short,short); void X3(char *,short,char *); void main(void) { char Str[][30]={"CDECDEGEDCDEC","CDE","AB"}; short Ret; Ret=X1(Str[0],Str[1],Str[2]); printf("Str[0] : %s\n", Str[0]); printf("Str[1] : %s\n", Str[1]); printf("Str[2] : %s\n", Str[2]); printf("Ret : %d\n", Ret); } short X1(char *pStr1,char *pStr2,char *pStr3) { short Len1,Len2,Len3; short Cnt1,Cnt2; short Ret = 0; for (Len1= 0;pStr1[Len1]!=0;Len1++); for (Len2= 0;pStr2[Len2]!=0;Len2++); for (Len3= 0;pStr3[Len3]!=0;Len3++); if (Len1<Len2 || Len2==0) return Ret; for (Cnt1=0; Cnt1<=Len1-Len2; Cnt1++){ for (Cnt2=0; Cnt2<Len2; Cnt2++){ if (pStr1[Cnt1+Cnt2]!=pStr2[Cnt2]) break; } if (Cnt2==Len2){ X2(pStr1,Cnt1+1,Len2); X3(pStr1,Cnt1+1,pStr3); Len1 += Len3-Len2; Cnt1 += Len3-1; Ret++; } } return Ret; } void X2(char *pStr, short Pnt, short Num) { short Cnt, Len; for (Len = 0; pStr[Len]!=0; Len++); for (Cnt = Pnt+Num-1; Cnt<=Len; Cnt++){ pStr[Cnt-Num] = pStr[Cnt]; } } void X3(char *pDst, short Pnt; char *pSrc) { short SrcLen, DstLen; short Cnt; for (SrcLen=0; pSrc[SrcLen]!=0; SrcLen++); for (DstLen=0; pDst[DstLen]!=0; DstLen++); for (Cnt=DstLen-1; Cnt>=Pnt-1; Cnt--){ pDst[Cnt+SrcLen]=pDst[Cnt]; } for (Cnt=0; Cnt<SrcLen; Cnt++){ pDst[Pnt+Cnt-1]=pSrc[Cnt]; } pDst[DstLen+SrcLen]=0; } というようなプログラムの出力結果はどうなるか?という問題ですが、Str[0]:ABABGEDABC, Str[1]:CDE, Str[2]:AB, Ret:3となるんですが、どうしてそうなるかが、全然分かりません。どなたか説明してもらえないでしょうか?お願いします。

  • ポインタ勉強中です。しかも実行するとおかしいです。

    <本に載ってたソース> #include<stdio.h> #include<string.h> int main() { char msg[20]; char *str=NULL; int i; int cnt; str=&msg[0]; printf("文字を入力してください"); scanf("%s",&str); cnt=strlen(msg); str=msg+cnt; for(i=cnt;i>=0;i--){ printf("%c",*(str--)); } printf("\n"); return 0; } char *str=NULL;は、ポインタstrを空にするということでしょうか? いつもながらstrlenとsizeofが混じります。 sizeofがバイトの大きさで、strlenが、文字数でしたっけ?

  • 「ポインタのポインタ」を使った文字列のソート方法?

    初めて質問を投稿させていただきます。 どうぞよろしくお願いします。 現在、C言語の勉強として、 「ポインタのポインタ」を使って「コマンドラインから入力された複数の文字列を昇順にソートして表示するプログラム」 を作っているのですが、 (main関数とソート用関数は分け、出力処理はmainの中でやります) 引数として何を渡せばいいのか、またソートで何を比較して、何を入れ替えれば良いのか、考えれば考えるほど混乱してしまいます。 (過去の質問も一通り調べてみたつもりですが、解決の手がかりとなるものが見つかりませんでした) それで、どうコーディングすればいいのかを解説して頂きたいのですが、 投稿できる文字数が限られているという事なので、私が未熟なりに作ったプログラムを、見て頂くに必要と思われる部分のみ載せさせて頂きます。 int main(int argc , char** argv) { int i = 0; /* カウンタ */ sort(argc-1,argv+1);/* sort関数 */ for(i = 1 ; i < argc ; i++) /* 出力ループ */ { printf("%s\n",*(argv+i)); /* ソート後文字列出力 */ } return 0; } /* main関数ここまで */ void sort(int sargc,char** sargv) { int i1 = 0; /* ソート用カウンタ・一時領域 */ int i2 = 0; char* temp = NULL; for(i1 = 0 ; i1 < sargc - 1 ; i1++) { for(i2 = i1 + 1 ; i2 < sargc ; i2++) { if(*(sargv + i1) < *(sargv + i2)) { temp = *(sargv + i1); /* 入れ替え */ *(sargv + i1) = *(sargv + i2); *(sargv + i2) = temp; } } } return; } } なお、実行結果は、例えば、 「実行ファイル名 suzuki tanaka satou」 と入力すれば、 satou suzuki tanaka と出力されるようにしたいと考えています。 どうぞよろしくお願いします。

  • returnと条件式内の代入

    Cでmemcmpライクな関数が必要になり作りました。(正確には中でmemcmpを何回か呼び出して比較をする関数) そのときに出た疑問なのですが、ループ内でif文→returnとするのと、ループの条件にif文の条件を織り込んで、関数の最後でreturnするのとどちらが良いのか。 作った後で、いくつかのサイトでreturnはまとめるほうがいいとありましたので2つめの関数も考えました。しかし、条件式に=(代入)を書くのは好ましくないとする考えもあるようで、もう一つ作りました。しかし、初期化直後のretを比較するのは気分が悪いのです。悩んでいます。つまり、次のような関数でより好ましいのはどれでしょうか? (いずれも質問用にmemcmpに書き直してます) int mymemcmp(const void *a, const void *b, size_t cnt) {   const unsigned char *ap = a, *bp = b;   int i, ret;   for (i=0; i<cnt; i++)   {     ret = ap[i] - bp[i];     if (ret != 0)     {       return ret;     }   }   return 0; } int mymemcmp(const void *a, const void *b, size_t cnt) {   const unsigned char *ap = a, *bp = b;   int i, ret=0;   for (i=0; i<cnt && (ret = ap[i] - bp[i]) == 0; i++)     ;   return ret; } int mymemcmp(const void *a, const void *b, size_t cnt) {   const unsigned char *ap = a, *bp = b;   int i, ret=0;   for (i=0; ret == 0 && i<cnt; i++)   {     ret = ap[i] - bp[i];   }   return ret; }

  • C言語の、戻り値/値渡し/アドレス渡しのついて

    【実装したコードに、戻り値/値渡し/アドレス渡しを用いたサブの関数を作成せよ。】 上記の課題に取り組んでいるのですが、何となく概念は分かったのですが、ソースコードに反映させようとすると詰まってしまって… どなたか教えて頂けないでしょうか? 『ソースコード』 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char e[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1,&op, &num2); if (r != CALC) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s", e); if (strcmp(e, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • ポインタ

    字列2つを入力し,同じ文字列かどうかを判定するプログラム ポインタの操作で文字列の比較を実現する。 (ライブラリ関数 strcmp を仕様しない) 関数の中身が上手に実現出来ません。 文字列を指すポインタ変数 2 つを引数に取り,同じ文字列なら -1 を,異なる場合は先頭から一致した文字数 を返す関数 必ず,具体的な解答を提示して下さい。 char str__com(char *s,char *t,int count) { while(*s = *t != '\0'){ if(s != t){ return -1; } if(s == t){ count++; } {s++;t++;} } return -1; }

  • プログラミング ポインタを使った文字列比較

    プログラミング ポインタを使った文字列比較 2つの文字列str1, str2を入力し,それらが等しければ0,等しくなければ1を返す関数str_compareを作り、返り値によって以下のように表示するプログラムを作れ。ただし,関数strcmpを使ってはならない。 文字列の入出力はmain関数で行い,関数str_compareの仮引数にはポインタ変数を宣言し,ポインタと間接演算子*を用いた処理を行うこと。 % ./a.out input str1 = Worldcup input str2 = Worldcup same strings % ./a.out input str1 = World input str2 = cup different strings この問題に私は次のようにプログラミングしました。 #include <stdio.h> #define MAX 100 int str_compare(char *, char *); main() { char str1[MAX], str2[MAX]; printf("input str1 = %s", str1); scanf("%s", str1); printf("input str2 = %s", str2); scanf("%s", str2); str_compare(str1, str2); if (str_compare(str1, str2) == 0) printf("same strings\n"); else if (str_compare(str1, str2) == 1) printf("different strings\n"); } int str_compare(char *s1, char *s2) { int i; for (i = 0; s1[i] != '\0'; i++) { if (s1[i] != s2[i]) { break; } } if (s1[i] == s2[i]) { return 0; } else { return 1; } } これで実行したところ、「input str1 =」の右のスペースが文字化け?してしまいます。(半角カタカナや記号が出る)ただ、その後に文字列を入力すると、正しく機能します。 これは何が悪いなのでしょうか、どなたか教えてください。

  • 加算、減算、乗算、除算について

    // 加算、減算、乗算、除算について // 記号と数値にそれぞれ別の配列に分けました。 // そこから、どうすれば計算ができるのか // 悩んでいます。よろしくお願いします。 #include<iostream> using namespace std; char **tokei(char *str1,char *str2,int *count,char *kigouX); int main() { int count; int *num; char **www; char kigo[12]; char str1[30],str2[]="+-*/"; strcpy(str1,"123+45-6*789/"); www=tokei(str1,str2,&count,kigo); num=new int[count]; for(int n=0;n<count;n++) { num[n]=atoi(www[n]); } // 数値に変換num[]、記号を順番に抽出kigo[] -->OK // 記号に沿って、数値を演算すればよい。 // ここがやり方(理屈)がわからない。 getchar();{}return 0; } char **tokei(char *str1,char *str2,int *count,char *kigouX) { int cnt=0; int m=0; for(int a=0;*(str1+a)!='\0';a++){} for(int b=0;*(str2+b)!='\0';b++){} for(int i=0;i<a;i++) { for(int j=0;j<b;j++) { if(*(str1+i)==*(str2+j)) { *(kigouX+m)=*(str1+i);m++; *(str1+i)='\0'; cnt++; } } } *(kigouX+m)='\0'; char **c; c=new char*[cnt]; *count=cnt; for(int m=0;m<cnt;m++) { c[m]=str1; while(*str1!='\0'){str1++;}str1++; } return c; }

  • Cのポインタについて

    int howiwork(char *s, char **tab) { int i; if( s == NULL ) return ERROR; for ( i = 0;*tab;tab++,i++) if(! strcmp(s,*tab)) return i; return ERROR; } このプログラミングの機能を教えていただきたいのですがお願いします。

  • 配列のアドレス渡し

    今までの質問にも似たような例がありましたがなかなか解決できません、教えてください。 下のプログラムを実行すると(省略アリ) #include<stdio.h> #include<string.h> #define N 32 char sort(char*,char*); main(int argc,char *argv[]) { char read[N*N],CASL[N][N][N]; sort(CASL,read); } void sort(char *CASL,char *read) { int i=0,j=0,k=0,z=0; while(1){ if(*(read+z) == '\0') break; else if(*(read+z) == ' '){ *(CASL+i*N*N+j*N+k) = '\0'; j++;k=0; } else if(*(read+z) == '\n'){ *(CASL+i*N*N+j*N+k) = '\0'; i++;j=0;k=0; } else{ *(CASL+i*N*N+j*N+k) = *(read+z); k++; } z++; } } warning: passing arg 1 of `sort' from incompatible pointer type のエラーメッセージがでてしまいます。関数間での受け渡しで発生しているエラーだと思うのですが、どこを直せばいいのでしょうか?教えてください。 あと、できれば3次元配列はそのまま使いたいです。

専門家に質問してみよう