• ベストアンサー

配列について

こんにちは。 int p[1000]という整数型の配列を作成しました。 例えば、 p[0] = 1; p[1] = 2; p[2] = 3; ・ ・ ・ p[99] = 100; を格納し、配列の長さ?を調べる際、 unsigned int len = 0; while(p[len]!='\0') len++; とすることで調べることが可能でしょうか?p[100]番以降に0が格納されている場合それがナル文字となるのでしょうか? また、char c[1000]と文字列型の配列を作成し、文字列の数値を格納していく場合、一桁であれば要素1個(1Byte?)で格納できますが、二桁以上であれば要素2個以上(2Byte以上←あっていますでしょうか)必要です。 c[0]='1' c[1]='2' c[2]='3' c[3]='4' ・ ・ ・ c[9]='1' c[10]='0' c[11]='1' c[12]='1' ・ ・ ・ ここで問題なのですが、文字列10と文字列11の判別はできないのでしょうか? 110111が連続している場合も値110と値111と判別できないのでしょうか? 値を格納する場合は、整数型のint c[1000]を用意するという事でしょうか? よろしくお願いします。

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

  • ベストアンサー
  • nerosuke
  • ベストアンサー率33% (39/115)
回答No.6

>通常は一元配列ではなく二次元配列をつかいます。 2次元配列を使うことで解決するのでしょうか? 扱うデータの量にもよります。 そのまま配列で文字列で送るなら二次元配列でいいんじゃないでしょうか?ただchar型も一バイトのサイズを持った変数なのですから、 unsigned なら255 signed-127~127の整数は扱えます。 もしくは、文字列ではなく整数型に変換し、整数型の1次元配列へ格納し送信することも考えられるのでしょうか? 考えられます。 ソケットにおいては多少強引にでもデータ量を節約する事もありますので、一概には言えませんが・・・ >一旦atoi関数にて整数型に変換した上で、比較することになるのでしょうか C言語には文字列型というものがありませんので、そのまま式で比較は できませんが、比較する標準関数は用意されています。 参考になるサイトを張っておきます。 http://www.st.rim.or.jp/~phinloda/cqa/cqa2.html ついでに、最小単位のパケットの構造体を作ってsendすればいいのではないでしょうか? さらに言えばchar型の配列で送ったとしてもrecv先で構造体のポインタにキャストしてしまってもいいです。 最後に質問にソケットと書いておけば印象が変わるので、回答も変わってきますので次回からは書いたほうがいいです。

bird0214
質問者

お礼

返信ありがとうございます。 確かに、最小単位のパケットの構造体を作ってsendtoすればよいかもしれません。参考にさせていただきます。 まだ・・分からないところがありまして・・・ またこの掲示板を利用させていただきます。 ありがとうございました。

その他の回答 (5)

  • Ka-Wa
  • ベストアンサー率46% (12/26)
回答No.5

まず、C言語の話でいいですよね? ・int型の値"0"と、ナル文字'\0' は意味合いが異なりますが、プログラムの動作上はどちらも "ゼロ"の値をとりますので、無理やり比較した場合は両者はイコールの結果になります ・配列で、値を設定されていない要素の値は一般に保証されません(ゴミがのって不正な値になる場合が大半です)。あらかじめmemset等でゼロクリアしておかないと、未設定の配列要素が"0"になっているとは限りません 以上より、「配列の長さ(?)」を求める上では、 ・整数値を格納する配列の場合は、配列の長さをあらかじめ別の変数に退避させておくプログラミングが現実的です(配列への要素書き込み時にインクリメント等実施する) ・あるいは、配列の終了を示すコードとして、他の要素が「絶対に使わない値」を書き込む必要があります。整数配列の場合はたいていの場合「0」を利用することは適切ではないでしょう。 文字列を配列に格納する場合は、通常文字コードはゼロ値'\0'は文字列の中では利用しないため、配列の終了を示すものとしての利用が可能であり、また一般的です。

bird0214
質問者

お礼

返信ありがとうございます。 配列の終了を示すコードとして、整数型の配列では「0」を利用せずある特殊なコードを利用するとのご指摘ですね! 今後気をつけたいと思います。 ありがとうございました。

  • nerosuke
  • ベストアンサー率33% (39/115)
回答No.4

No3です。 私の回答が言葉足らずでしたので補足いたします。 質問者の意図が数値を全角で表示したいのだとして、 私が示したのは1例であって質問者のやりたい事は色んな方法でできます。 ・テーブルでの参照(私が回答したものです。) ・sprintfの使用 ・itoa関数 etc もしくはそのまま一次元配列でデータを扱いたいなら、 連続する文字列の終わりに'\0'を入れて参照する方法もできますが、普通はそんなやりかたはしません。 数値で格納して変換して表示ってのが一番簡単だと思います。

bird0214
質問者

補足

申し訳ありません、もうひとつ質問なのですが・・・ 例えば、文字列'1' '0' '0'と'1' '0' '1'を比較する場合(値100と101の比較を言っています)、文字列ではなく一旦atoi関数にて整数型に変換した上で、比較することになるのでしょうか? よろしくお願いします。

  • nerosuke
  • ベストアンサー率33% (39/115)
回答No.3

>unsigned int len = 0; >while(p[len]!='\0') >len++; >とすることで調べることが可能でしょうか?p[100]番以降に0が格納さ>れている場合それがナル文字となるのでしょうか? 数値の比較なので while( p[len] ) { } でいいです。 ちなみにナル文字じゃなくてヌル文字です。 >ここで問題なのですが、文字列10と文字列11の判別はできないのでし >ょうか? 110111が連続している場合も値110と値111と判別できない >の でしょうか? やってできない事はないですが、目的がわかりません。 やりたい事はわかりました。おっしゃる通り文字列になります。 通常は一元配列ではなく二次元配列をつかいます。 ただ数値を全角にしたいだけなら数値のテーブルを作って一桁づつ表示すれば簡単ですよ。 char *numTbl[]={"0","1","2","3","4","5","6","7","8","9"}; あとは数値の桁に合せてテーブルを参照する。 桁の求め方は位で割ったり余りを求めれば簡単に出ます。 とりあえず何故そうしたいのか?という目的がわかりませんので 目的(理由)を書いたほうが良回答が得られます。

bird0214
質問者

補足

返信ありがとうございます。 >とりあえず何故そうしたいのか? 何をしたいかを明確に伝えることが難しく、少し簡単なプログラムを作成してから発展させようかと考えていました。 今現在行っていることは、ソケットプログラミングです。 送信側と受信側2台を用意し、 送信側から各パケットに通番を割り振り、受信側へ送信します。 受信側は、通番を確認し受信側で取得できなかった通番を送信側へ送信します。 この際、受信側で取得できなかった通番を文字列として配列内へ格納し送信側へ送信しようとしています。例えば100と110が格納されたとします。 buf[0]:'1' buf[1]:'0' buf[2]:'0' buf[3]:'1' buf[4]:'1' buf[5]:'0' と一次元配列で格納した場合値100と110の判別が送信側でつくのか?と言う意味です。 nerosukeさんがおっしゃるとおり、 >通常は一元配列ではなく二次元配列をつかいます。 2次元配列を使うことで解決するのでしょうか? もしくは、文字列ではなく整数型に変換し、整数型の1次元配列へ格納し送信することも考えられるのでしょうか? よろしくお願いします。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

int型なら普通に整数値と比較するのがいいと思います while (p[len] != 0) char c[1000]は文字列型の配列ではなくて文字の配列、または1個の文字列と考えた方がいいと思います。 文字列の配列ならchar c[1000][5]とすれば4桁(文字列の最後に\0が入るため)の文字列が1000個使えます。 char c[1000][5]; c[1][0] = '2'; c[1][1] = '\0'; strcpy(c[999], "1000"); printf("%s %s", c[1], c[999]);

bird0214
質問者

お礼

返信ありがとうございます。 1次元配列ではなく2次元配列を利用することが通説であることを知りました。 ありがとうございました。

noname#22058
noname#22058
回答No.1

> while(p[len]!='\0') おそらく、正しい答えを得るでしょう。 しかし、pはint型ですから、素直に 0 と比べる方が より自然でありましょう。

bird0214
質問者

お礼

返答ありがとうございます。 '\0'ではなく素直に0を用いればよいとのことですね! ありがとうございました。

関連するQ&A

  • 配列

    String型の配列の中の文字列の文字数を数える方法で困っています。 問題は、int型の変数lenで与えられた数字よりも大きい文字数の文字列はいくつあるか調べます。 例) stringsLongerThan({"a","ab","abc"}, 0) 3つ全ての文字列の文字数は0より大きいので3を返す stringsLongerThan({"a","ab","abc"}, 2) "abc"の文字数が2より大きいので1を返す stringsLongerThan({"a","ab","abc","abcd","abcde","abcdef","abcdefg"}, 3) "abcd","abcde","abcdef","abcdefg"の4つが文字数3より大きいので4を返す 途中まで組んだのですが、配列array[]の中の文字列の文字数を数えるにはどうしたらよいのでしょうか? public int stringsLongerthan(String[] array, int len){       int result=0;      for(int i=0;i<array.length;i++){        //ここで配列array[i]の文字列の文字数を数える       int count=文字数;       if(cont>len)        result++;     }      return result; } 宜しくお願いします。

    • ベストアンサー
    • Java
  • c言語 int型の数字をchar型の配列に

    c言語についてです。 int型の数字をchar型の配列に入れたいです。 関数に対してint型の数字を文字列として渡し、 関数内でchar型の配列に格納したいです。 例として、 a(char a[]){  ~~  ~~ } int main(void){ int x = 5678;  ~~  a(x); } とできるようにしたいです。 しかしこれだと5678という値がそのままchar型の一つの配列に入る?ため正しくないです。 欲しい結果としてはちゃんとa関数内で、 a[1] = '5' a[2] = '6' a[3] = '7' a[4] = '8' となってほしいです。 もともと渡す値が”5678”となっていれば結果は正しく出るのですが、 渡す値がint型と決まっているためどうにかして5678を”5678”とすればいいのではないかと考えています。 つまり5678を単純に文字列に変換すればいいのでしょうか? またプログラム内ではsprintfやatolを使用しないで実現させたいです。 難しいかもしれませんがお願いします。 なんだか説明が下手ですみません。 お願いいたします。

  • String配列を扱うアルゴリズムについて

    よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • 二次元配列で"一列"取り出すには?

    すいませんC# を勉強中なのですが、 たとえば int[,] a = new int[2,2] {            {1,2},            {3,4}         } という2x2の二次元配列があったとき 縦の列、つまり1と3だけ抜き取って配列に格納したい、または2と4だけを抜き取って配列に格納するにはどうすればいいでしょうか? 実際には配列に抜き取った後に hairetsu.Max(); でその列の最大値を出したいと考えています。 たくさん量があるとき、どうすれば簡単に列の配列を抜きとれるのでしょうか、ご存じの方よろしくお願いします…

  • 整数分割

    乱数で発生させた整数を配列に格納してその配列の整数を桁ごとに分割する簡単な方法はありますか。 例えば123を1と2と3に分割 整数を文字列に直して分割しようとしたけど整数は配列に格納されている (a[0]=123のように)のでできません。javaでプログラムを教えてください

  • C# 配列の配列(多次元配列?)

    C#において、配列の配列中に格納した値を、検索することを 行いたいのですが、格納した値そのものを見ることができません。 まだ、C#を始めて間もないので、配列に格納する時点で、 不備があるかも知れませんが、お願いします。 やりたいこと ・テキストファイル内にある値を、2次元配列または、多次元配列に格納 ・配列に格納した値で、データチェックなどを行う予定  テキストファイル内のデータは、下記内容となり要素数も固定ではなく変動する   A=1,2,3・・・   B=11,22,33・・・ 実際のソースは、 //配列 ArrayList list = new ArrayList(); //配列格納 1レコード毎用 ArrayList listtmp = new ArrayList(); while ((strGenderTextLine = objReader.ReadLine()) != null) {  string strBuffer;  //「=」前の値格納用変数  string[] strBuffer2; //「=」後の値格納用配列  listtmp=null;  //strtmpに「=」前の値を格納  strtmp = TextLine.Split('=').GetValue(0).ToString();  //strtmp2に「=」後の値を格納(配列)  strtmp2 = TextLine.Split('=').GetValue(1).ToString().Split(',');  for (int i = 0; i <= strtmp2.Length - 1; i ++)  {   //[i,0]に、「=」前の値を代入   if (i == 0)   {   listtmp.Add(strtmp);   }   else   {   listtmp.Add(strtmp2[i].ToString());   }  }  //list配列にlistTmp配列を格納(配列の配列)  list.Add(listtmp);  intT = intT + strtmp2.Length;  //行数カウント  intTLine = intTLine + 1;  } ここから、配列「list」内に入っている値を閲覧することができる方法を教えていただければと思います。 宜しくお願いいたします。

  • 大きさがわからない配列

    String型の配列で、文字列を格納していきたいのですが、 格納する文字列はいくつ来るかわかりません。 配列を大きさを確保しないで、どんどん文字列を 格納していくことはできますか? ブログのURLを格納するのですが、

    • ベストアンサー
    • Java
  • C♯の配列について

    C♯でプログラムを作っているのですが、配列の要素数の最大値と最小値の求め方がわかりません。配列の値の最大値の求め方は調べれば出てくるのですが、要素数の最大値等は調べてもわかりませんでした。 例えば下記のような配列があった場合 int[,,] a =new int[100,100,100] a[2,3,6]=1 a[4,5,9]=1 a[13,46,79]=1 a[8,15,45]=1 a[1,33,68]=1 それぞれの要素数の最小値1、3、6、最大値13、46、79は どのようにプログラムで求めればいいのでしょうか? よろしくお願いします。

  • C#で配列の値をチェックするメソッドを書きたい

    C#の配列についてお教え頂けませんでしょうか? CSVファイルから1行読取り、配列に格納しています。 string[] rowdata; string x; int y; double z; TextFieldParser Parser = new TextFieldParser(FILEPATH, Encoding.GetEncoding("shift_jis")); while (!Parser.EndOfData) { //1行読取り rowdata = csvParser.ReadFields(); //読み取った値を変数に x = rowdata[0]; //string y = rowdata[1]; //int z = rowdata[2]; //double } rowdata[0~3]を変数に格納する前に、データのチェックをおこないたいです。 例えば、rowdata[1]はint型変数に格納されます。しかしrowdata[1]に格納された値が「A1」とあった場合、int型変数yには格納できずエラーが起こります。 よって、rowdata[1]に数値以外の文字列があったら「0」に置き換えるなどの処理をいれたいです。 なので、配列を受け取ってデータチェックをするメソッドを作りたいと思いますが、どのように作っていいかがわかりません。 1つのメソッドでint、double、stringかどうかの、チェックを行いたいですが、そのようなことは可能なのでしょうか? 下記のように3つメソッドを作って、データをメソッドに渡しチェックを行なうのがいいのでしょうか? string CheckData(string[] arr){}; int CheckData(int[] arr){}; double CheckData(double[] arr){}; やりたい事は、 メソッド(配列を受取る) rowdata[0]が渡された場合、中身はstringかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[1]が渡された場合、中身はintかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[2]が渡された場合、中身はdoubleかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 以上のような事です。宜しくお願い致します。

  • 整数型の配列を文字型の配列にコピーするとき

    こんばんは。 いつもお世話になっています。 また初歩的な質問で申し訳ないのですが、どうかよろしくお願いします。 今、プログラミングの本を見ていたら、snprintfを使って、 整数型配列の1つの要素を文字型配列にコピーしている箇所がありました。 そのときに、 int i[2]; char ch[3]; snprintf(ch,sizeof(ch),"%d",i[0]); のようにあったのですが、なぜこのとき文字型配列は要素数が3で宣言しておく必要があるのですか? (今i[0]に何が入っているのかはわかりませんが、3~1024までの整数であることは確かです。) どなたかお答えお願いします。

専門家に質問してみよう