• ベストアンサー

配列の要素数が変化する・・・

自分ではどうしても解決不可につき、教えてください。 main関数で入力文字列「input」の要素数は256なのに、検索キー入力チェック関数で出力引数となるポインタ「pOutInput」の要素数は4なんです…。 ちなみにこれが4だと、fgetsで5文字('\n'を除くと4文字)読み込みたいのに、fgetsが2回読み込みに行ってしまうんです。 fgetsの読み込み数を10など、5文字以上に指定すれば読み込めますが、sizeof(pOutInput)の4を超えているので、ホントはよろしくないはずですよね? sizeof(pOutInput)がmain関数と同じ256になる方法、教えていただけますでしょうか? よろしくお願いします!! //main関数 int main() { char input[256]; /* 入力文字列input */ /* 検索キー入力チェック関数呼び出し */ InputSchKeyCk(input); printf("kekka:%s\n", input); return 0; } //検索キー入力チェック関数 int InputSchKeyCk(char* pOutInput) { /**== 変数宣言 ==**/ int flgInput; /* 入力続行フラグ */ /**== 初期化処理 ==**/ flgInput = 1; /**== 入力チェック処理 ==**/ /* 入力続行フラグが入力続行の限りループ */ while(flgInput == 1) { /* 入力社員IDをキーボード入力受付 */ printf("検索対象社員の4桁の社員IDを入力してください。\n"); fgets(pOutInput, sizeof(pOutInput), stdin); /* 入力社員IDの文字長が4以下、または6以上 */ if(strlen(pOutInput) != 5) { /* 画面にエラーメッセージ出力 */ printf("社員IDは4桁で入力してください。\n"); } else { /* 入力続行フラグに入力中断を代入 */ flgInput = 0; } } /**== 正常終了 ==**/ return 0; }

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

  • ベストアンサー
  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.1

こんにちわ。 > main関数で入力文字列「input」の要素数は256なのに、 > 検索キー入力チェック関数で出力引数となるポインタ > 「pOutInput」の要素数は4なんです…。 InputSchKeyCk 関数内でsizeof しているのは、単なるポインタ なので4 Byte と判断しているだけです。 要は領域をアドレスだけ渡されたのでは、渡された方はどれだけの 領域がとられているか分からないと言う事です。 解決方法としては、 1. InputSchKeyCk 関数にinput 領域のサイズも一緒に渡してやる。 2. 「#define BUFFER_SIZE 256」と宣言して、main 関数での領域確保 は、char input[BUFFER_SIZE] とする。 → InputSchKeyCk 関数では、sizeof() を使わずに、 BUFFER_SIZE を使う。 3. input 変数をグローバルにして、sizeof(input) とする。 等の方法があります。 私としては、2 がお奨めですね。

marimo109
質問者

お礼

muyoshidさんっっ、的を得た答えをホントにありがとうございました!! muyoshidさんオススメの2番の方法でやってみました。 ばっちりできました。 ちなみにこの関数が何の目的のmain関数の一部だったかというと・・・ 「社員IDと社員名が入ったテキストファイルを読み込んで構造体に格納し、さらに検索する」関数の社員IDの"文字数チェック"だったワケです。 おかげさまで全部コーディングでき、正常に動いてくれました☆ この関数、ユーザ定義関数が4つあるんですけど、ユーザ定義関数があって正常動作してくれたの、今回が初めてなんです!! すごくうれしかった~!! muyoshidさん、最後にもう一度、ありがとうございました!!!

その他の回答 (1)

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

#1-1に一票

marimo109
質問者

お礼

BLUEPIXYさんも、ありがとうございました。 また何かあったら、よろしくお願いしますね!!

関連するQ&A

  • 配列渡し後の要素数を知るには・・?

    main関数で定義した配列を他の関数で扱う場合にどうすればいいのかいまいちわかりません・・。 微妙に独学したのですが sizeofで要素数を調べたいのですがどうすればmain以外の関数内で要素数を調べる事ができるのでしょうか。私の書いたソースはこれです。 void dis(int *b){ int i, nx; nx = sizeof(b) / sizeof(b[0]); for(i=0;i<nx;i++){ printf("%d\n", *(b+i)); } } main(){ int a[5] = { 10, 20, 5, 1, -1 }; dis(a); return(0); } どうすればいいでしょうか・・・。どなたか教えていただければ光栄です。ご指導お願いします!

  • 引数で指定された配列の要素数の取得

    どうもこんにちは。 C言語でプログラムを作成しています。 ある関数に配列を渡すことを考えていますが、渡した配列の要素数を取得する方法は何かありますか? 標準の関数を見ても、配列の先頭アドレスのポインタとともに、配列の要素数を渡しているものばかりで、配列のポインタを渡しているものは見かけません。 要素数があらかじめわかっていれば、それを引数の型に指定できますが、呼び出されるまで不明な場合はうまくいきません。 配列の要素数も引数として一緒に渡す必要がありますか? [作ってみたサンプル] #include <stdio.h> #include <stdlib.h> #include <string.h> // func1 と func2 をまとめられないだろうか。。。 void func1(int (*p)[10]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } void func2(int (*p)[5]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } int main(int argc, char *argv[]) { ________int ary1[10] = { 2, 4, 6, 8, 0, 1, 3, 5, 7, 9 }; ________int ary2[5] = { 3, 6, 9, 12, 15 }; ________func1(&ary1); ________func2(&ary2); ________return 0; }

  • 配列の要素の入り方

    こんばんは。 現在C言語のプログラミングを勉強しています。 まだまだ初心者で基礎も十分には理解できていないので、とても基本なのかもしれませんが質問させていただきます… 例えば以下のような、配列に文字を入力するだけのプログラムを作ったとします。 --------------------------------- #include<stdio.h> main(){  int data[10];  printf("input - ");  fgets(data,10,stdin); } --------------------------------- これを実行し、 input - abc のように「abc」と入力すると、配列にはどのように入るのですか?  data[0]=a, data[1]=b, data[2]=c となるまではわかるのですが、data[3]からdata[9]には何が入るのでしょうか。配列のクリアはしていない状態です。 改行とnullが入る、というように聞いたのですが、これらはどのような順(?)で配列に入っているのかがわかりません。 よろしくお願いします。

  • c言語 文字列と配列

    #include<stdio.h> int charlen(int n); void cap2sml(int b); int main() { char a[100],b[100]; int n,i; /*Input CARACTERS*/ printf("CAPITAL?\n"); fgets(a,100,stdin); charlen(n); printf("total cahrs=%d\n",n); //printf in main cap2sml(i); printf("small=%s\n",b); return(0); int charlen(int n) n=0; while(1){ if(a[n]=='\0') break; n++; } void cap2sml(int b) int i; for(i=0;a[i]!='\0';i++){ b[i]=a[i]+0x20; } b[i]='\0' } のプログラムでエラーがでるのですが、どこを直せばよいでしょうか? ユーザー関数を使い文字列(大文字)を入力したときの文字列の長さと大文字を小文字に変化するプログラムです

  • 配列とfor文の組み合わせがうまくいきません

    初心者なので質問文でおかしなことを言ってるかもしれませんが よろしくお願いします ソースは下に貼り付けました。 コースの数を入力し、そのコースに名前をつけるという プログラムを書いたのですが forでcoursename[0]からcoucename[3]までの4つに名前を入力しようと コース数に「4」を入力しても forによって繰り返されるのは coursename[0]からcoucename[2]までの3つでした どう直せばいいのでしょうか ==================================================== #include <stdio.h> #define MAX_COURSE 5 /*最大数*/ int main(void){ int course = 0; /*コース数*/ char coursename[MAX_COURSE][100]; /*コース名*/ char line[100]; /*入力用文字型配列*/ int i; /*コース数の入力*/ while (course < 1 || 5 < course){ printf("コース数の入力を行ってください。(1~5)\n"); printf("INPUT : "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &course); } /*コース名の入力*/ printf("コース名の入力を行ってください。\n"); for(i=0; i<course-1; i++){ printf("%d科目 : ", i+1); fgets(line, sizeof(line), stdin); sscanf(line, "%s" , coursename[i]); } return 0; } ====================================================

  • 配列要素内の数値

    #include <stdio.h> int main(void) { int arr[1]={123456789}; int *x[1]; *x = arr; printf("%d ",*(x[0])); /* 123456789 と表示*/ return 0;} 実行すると123456789と表示されるまでは分かるのですが、*(x[0])の部分を別の書き方にして、arr[0]に入ってある「123456789」という数値の千の値である6という数値のみを取り出して、表示することは可能なのでしょうか?(6000と取り出したいのではなく、6として取り出したい) 次のように数値を文字列の一つ一つを扱うかのように、扱いたいのです。*(x[0])の部分の変更だけで6を取り出せるような方法はありますか? #include <stdio.h> int main(void) { char *arr[]={"pen"}; printf("%c\n",*(arr[0]+0)); printf("%c\n",*(arr[0]+1)); printf("%c\n",*(arr[0]+2)); return 0;}

  • fgets関数を使用したときの文字あふれについて

    fgets関数を用いて文字列を入力し、その長さを測るプログラムを作っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main ( int, char *[] ); int main ( argc, argv ) int argc; char *argv[]; { char buf[( MAX )]; while ( 1 ){ memset ( buf, 0, sizeof( buf )); fgets ( buf, MAX, stdin ); if( fgets == NULL ){ break; } printf("入力した文字列の長さは%dです\n" ,strlen( buf )); } return 0; } このプログラムでは、256までしか文字列の長さを測ることができません。 もしこのプログラムで256を超える文字列を入力してしまうと、文字のあふれが発生し、 「入力した文字列の長さは256です」 「入力した文字列の長さは(あふれた文字列の長さ)です」 とこのようになってしまいます。 このプログラムで256以上の文字を読み捨てて、 「入力した文字列の長さは(あふれた文字列の長さ)です」 を表示しないようにできるのでしょうか? また読み捨てた文字列の長さを知ることはできるのでしょうか? もしかしたらfgets関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。

  • 配列の要素数に変数を入れたい

    配列に数の入力履歴を入れて最後にその数を出力したいのですが、変数を入れることはできないと勉強した記憶がありまさにその通りコンパイルエラーが出ました。 他に何か方法はありませんでしょうか。 /* 課題1-3 */ #include <time.h> #include <stdio.h> #include <stdlib.h> #include <math.h> int main(void) { int i; int no1; /* 範囲1 */ int no2; /* 範囲2 */ int max; /* 大きい乱数 */ int min; /* 小さい乱数 */ int y; /* 当てさせる数 */ int stage; /* 入力回数 */ int x; /* 読み込んだ値 */ int n; /* 入力制限 */ srand(time(NULL)); no1 = rand(); no2 = rand(); if(no1 > no2){ max = no1; min = no2; } else{ max = no2; min = no1; } y = min + rand() % (max-min); n = ceil(log(max-min)/log(2)); int a[n]; /*←配列の要素数をn個にしたい*/ printf("%d以上%d以下の整数を当ててください。\n", min, max); stage = 0; do{ printf("残り%d回。いくつでしょう:\n", n - stage); scanf("%d", &x); a[stage++] = x; if(y > x) printf("小さいです。\n"); else if(y < x) printf("大きいです。\n"); }while(y != x && stage < n); if(y != x) printf("残念でした。正解は%dです。", y); else printf("正解です。%d回目で正解しました。", stage); puts("\n---入力履歴---"); for(i=0; i<stage; i++) printf("%2d : %4d %+4d\n", i+1, a[i], a[i] - y); return (0); }

  • 関数先にて配列の長さを取得する方法

    関数にて、引数にて渡された配列(ポインタ)から配列数を調べる方法はないでしょうか? #include <stdio.h> void test(unsigned int *p){ printf ("%d\n", sizeof(*p)/sizeof(p[0])); //結果 1 } int main(){ unsigned int hoge[] = {0x30, 0x31,0x32}; test(hoge); printf("%d", sizeof(hoge)/sizeof(hoge[0])); //結果3 return 1; } 上記コードの関数testの*pから配列の数3が抜き取りたいと思っております。 よろしくお願いします。

  • 要素数を100個にしろといわれたのですが

    要素数を100個にしろといわれたのですが int main(void){ char str="100"; printf("文字列を入力してください:"); scanf_s("%s",str); put_string(str); putchar('n'); return (0); } この『char str="100";』の部分を『char str[100];』にしたらいいんでしょうか? 教科書をみてやってみたのですがイマイチ理解できずお手上げ状態です 因みにC++です

専門家に質問してみよう