【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.21990

文字列の配列について
投稿者---ROLL(2005/07/19 23:03:05)


初めて投稿します。
以下のソースで
strcpy(swapbase_st[k].swapbase,p)として、
swapbase_st[k]に文字列を代入したかったのですが、
printf ("%s\n",swapbase_st[k].swapbase)のところで
実行時に異常終了します。
どのように修正すればよいでしょうか?よろしくお願いします。

OS:WinXP C-Compiler:BCC55です。

/* ファイル入力 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXRECORD_NUM 300
#define MAXFIELD_NUM 3000
#define RECORD_LENGTH 256
#define FIELD_LENGTH 26
#define FIELD_PER_RECORD 12


int main(void){
  FILE  *fin;
  char  infile[40],tp[RECORD_LENGTH],tp1[RECORD_LENGTH];
  char  array[MAXFIELD_NUM][FIELD_LENGTH];
  struct  s_struct { 
      char s[RECORD_LENGTH] ;
  };
  struct  swapbase_struct { 
        char  swapbase[FIELD_LENGTH];
    };

  int     j , k  , m, n ;
  int   swapnum[12];
  char  ti[] = "9999999999" ;
  char  *p ;
  int  recordcount = 0 , swap_table = 0, output_num = 0;
  struct  s_struct s_st[MAXRECORD_NUM];
//  struct  swapbase_struct swapbase_st[FIELD_PER_RECORD];

  struct  swapbase_struct *swapbase_st;

//メモリの確保

  if(!(swapbase_st=calloc(FIELD_PER_RECORD,sizeof(struct  swapbase_struct)))){
    printf("error in calloc");
  }

  
  swapnum[0] = 8;
  swapnum[1] = 3;
  swapnum[2] = 5;
  swapnum[3] = 6;
  swapnum[4] = 7;
  swapnum[5] = 9;
  swapnum[6] = 1;
  swapnum[7] = 4;
  swapnum[8] = 2;
  swapnum[9] = 10;
  swap_table = 10 ;
 /* 出力するときの順番を設定すると同時にswap_tableに項目数を代入している */

  printf("入力ファイル名=");
  gets(infile);
  /* 入力ファイルオープン */

  if((fin=fopen(infile,"r"))==NULL ){

    printf("ERROR \n");
    exit(1);
  }

  /* 一行ずつ読み出し */
//  while(fgets(s[i++],RECORD_LENGTH,fin)!=NULL){

//  printf("%s",s);

//  }


  while(fgets(tp,RECORD_LENGTH,fin)!=NULL){
    if ( strstr(tp,ti) != NULL ){ /* 9999999999が存在すれば */
      strcpy(s_st[recordcount].s,tp); /* INDEXが存在するレコード数が入る */
      printf ( "s=%s\n",s_st[recordcount].s);
      recordcount++;
    } /* if END */
  } /* while END */

  fclose(fin);

  

  /* INDEXが存在するレコードについてフィールドを配列に取り込む */
  for( j = 0; j < recordcount ; j++, k = 1){



    /* 一旦swapbaseにレコード中のフィールドを代入する */
    p = strtok(s_st[j].s,",");
          
    strcpy(swapbase_st[k].swapbase,p); /* 1回目のstrtok */
    k++;
//            printf ( "45\n");

//    p = strtok(NULL,",");

      printf ( "p=%s\n",p);
  while( p = strtok(NULL,",")){    /* 2回目以降のstrtok */
      strcpy(swapbase_st[k].swapbase,p);
      printf ( "p=%s\n",swapbase_st[k].swapbase);
//            printf ( "p=%s\n", p);

      k++;
    } /* while END */
            printf ( "456\n");

    /* swapbaseを並べ替え */
    for ( m = 1 ; m <= swap_table ; m++ ){
            printf ( "4567\n");
      for ( n = 1 ; n <= swap_table ; n++ ){
        if ( swapnum[n] == m ){
            /* swapbaseからswapnumの順に出力する。 */
            strcpy(array[output_num++],swapbase_st[n].swapbase);
            printf ( "678\n");
            printf ( "p=%s\n",swapbase_st[n].swapbase);

            break;
        } /* if END */
      } /* for n END */
    } /* for m END */
  } /* for j END */

  return(0);
}





この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:文字列の配列について 21992 rvr_driver 2005/07/19 23:44:20
<子記事> Re:文字列の配列について 21995 まきじ 2005/07/20 01:07:21
<子記事> Re:文字列の配列について 21996 まきじ 2005/07/20 01:22:23


No.21992

Re:文字列の配列について
投稿者---rvr_driver(2005/07/19 23:44:20)


コンパイルはきちんと通っていますか?
OS:WinXP C-Compiler:BCC55
の環境でコンパイルしましたが、以下のような警告が出ています。

警告 W8060 str_cp.c 35: おそらく不正な代入(関数 main )
警告 W8060 str_cp.c 98: おそらく不正な代入(関数 main )
警告 W8004 str_cp.c 27: 'swap_table' に代入した値は使われていない(関数 main )

きちんと警告が出ないようにしてみるといいのでは?
callocの行で問題ありそうなので異常終了しているようにみえます。


この投稿にコメントする

削除パスワード

No.21993

Re:文字列の配列について
投稿者---RAPT(2005/07/20 00:19:39)


余分なソースが多すぎるような気がします。
まずは事象が再現する最小のコードのみを掲載するよう、心掛けてください。

「事象が再現する最小のコード」を作成することによって、問題点が明確に
なったり、原因の切り分けができて、問題解決の近道になったりします。

# 問題文の printf... の個所をコピペして検索しても見つけられず、
# 目検しました。。どうせならそのままコピペして欲しかった。



この投稿にコメントする

削除パスワード

No.21994

Re:文字列の配列について
投稿者---rvr_driver(2005/07/20 00:24:30)


>callocの行で問題ありそうなので異常終了しているようにみえます。

に対して追加です。

while( p = strtok(NULL,",")){ /* 2回目以降のstrtok */

も警告が出ているのでもしかしたらこちらのほうに問題があって
異常終了しているかも知れません。

pの値を以下の文で調べてみてもいいかも。

if (p == NULL) printf("p is NULL\n");




この投稿にコメントする

削除パスワード

No.21995

Re:文字列の配列について
投稿者---まきじ(2005/07/20 01:07:21)


>実行時に異常終了します。
>strcpy(swapbase_st[k].swapbase,p)

の時点で、k が初期化されていないのが原因だと思います。



この投稿にコメントする

削除パスワード

No.21996

Re:文字列の配列について
投稿者---まきじ(2005/07/20 01:22:23)


>if(!(swapbase_st = calloc(FIELD_PER_RECORD,sizeof(struct swapbase_struct))))

は、if((swapbase_st = calloc(FIELD_PER_RECORD,sizeof(struct swapbase_struct))) == NULL)

>while(p = strtok(NULL,","))

は、while((p = strtok(NULL,",")) !=NULL)


この投稿にコメントする

削除パスワード

No.21997

Re:文字列の配列について
投稿者---ROLL(2005/07/20 07:07:21)


RAPTさん、rvr_driverさん、まきじさんどうもありがとうございました。
ご指摘の箇所を修正して、希望の動作が出来ました。

ループ中の初回のkにとんでもない値が入っていました。

>>if(!(swapbase_st = calloc(FIELD_PER_RECORD,sizeof(struct swapbase_struct))))
>
>は、if((swapbase_st = calloc(FIELD_PER_RECORD,sizeof(struct swapbase_struct))) == NULL)
>
>>while(p = strtok(NULL,","))
>
>は、while((p = strtok(NULL,",")) !=NULL)

これもありがたかったです。

コンパイルしたところ、swap_tableの値が使われていません
との警告が出るのですが、下のループ中で参照値として
使っています。これはどういうことでしょうか?

swap_table = 10 ;

for ( m = 1 ; m <= swap_table ; m++ ){





この投稿にコメントする

削除パスワード

No.21998

Re:文字列の配列について
投稿者---まきじ(2005/07/20 08:37:51)


>コンパイルしたところ、swap_tableの値が使われていません
>との警告が出るのですが、下のループ中で参照値として
>使っています。これはどういうことでしょうか?

私の環境ではでませんが?
「tp1[RECORD_LENGTH] が使われていない」とはでます。
tp1 は宣言だけされてるので、宣言を消せば警告もなくなります。


この投稿にコメントする

削除パスワード

No.22000

Re:文字列の配列について
投稿者---ROLL(2005/07/20 12:26:50)


>私の環境ではでませんが?
>「tp1[RECORD_LENGTH] が使われていない」とはでます。
>tp1 は宣言だけされてるので、宣言を消せば警告もなくなります。

そうでしたか。
私が環境設定を間違えたのでしょう。
tp1は宣言を消すのを忘れていました。
でもこちらの環境ではtp1のメッセージは出ないんですよね。
これも直しておきます。
具体的で的確なご指摘をいただき、
どうもありがとうございました。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧