アドレスのアクセス違反について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
SATOち

アドレスのアクセス違反について

#1

投稿記事 by SATOち » 14年前

はじめまして。
アドレスのアクセス違反について自力で解決を試みましたが、解決できず困っております。どうすれば解決できるでしょうか?

あるプログラムをデバックすると「matome_k.c.exe の 0x1026f824 (msvcr90d.dll) でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000031 を読み込み中にアクセス違反が発生しました。」という警告文が表示されます。

見づらいかと思いますが、一応、ソースコードも貼り付けておきます。

コード:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 256




/*メインモジュール*/
int main (void)
{
	 
		//youso = YOUSO();/*要素数モジュールを呼び出し*/
		
		struct	input{
		char	number;		/*部門コード*/
		char	comma1;		/*カンマ*/
		char	name[7];		/*商品名*/
		char	comma2;		/*カンマ*/
		}a[50];


	/*ファイルに出力するための構造体*/
	struct output{

	char	name1[7];	/*商品名*/
	char	comma1[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name2[7] ;	/*商品名*(予め固定長分の半角スペースで初期化)*/
	char	comma2[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name3[7];	/*商品名(予め固定長分の半角スペースで初期化)*/

	}data1;

	int ii =0;
	int count1 =0,count2=0;
	char buffer1[100][30],buffer2[100][30];
	int		kk;					/*添え字に使用*/
	char	comma2 =',';			/*コンマ*/
	int		jj;					/*添え字に使用*/
	char	comma1 =',';			/*コンマ*/
	FILE	*fp1;
	FILE	*fp2;
	FILE	*fp3;

		

		fp1 = fopen("list_input.txt","r"); 
		if( fp1 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		 //エラー処理
		}
	
	
	while(fread(&a[ii].number,1,1,fp1) != NULL){	/* 部門コードがある間データを読み込む */
			fread(&a[ii].comma1,1,1,fp1);			/* カンマ */
			fread(&a[ii].name,6,1,fp1);/* 商品名 */
			fread(&a[ii].comma2,1,1,fp1);			/*カンマまたは改行*/
			printf("%c",a[ii].number);

			if(strcmp(a[ii].number, "1") == 0) /*部門コードの確認*/
			{
				/*部門コード1*/
				strcpy(buffer1[count1],a[ii].name);/*部門コード1の商品名格納*/
				count1++;									/*次に格納する配列へ移動*/
			}else if(strcmp(a[ii].number,"2") == 0)
			{
				/*部門コード2*/
				strcpy(buffer2[count2],a[ii].name);/*部門コード2の商品名格納*/
				count2++;									/*次に格納する配列へ移動*/
			}else{
				printf("ERROR:判定不能な部門コードが検出されました。\a\n"); /*判定不能な部門コードが検出された場合、エラーメッセージを表示し強制終了する*/
				exit(1);
			}


			ii++;									/*次のデータへ移動*/
		}


	fp2 = fopen("list1.txt","w"); 
		if( fp2 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}
	

		for(jj=0;buffer1[jj][0]!=NULL;){	/*データが在るまで続ける*/
		
		sprintf(data1.name1,"%s",buffer1[jj++]);/* 商品名を挿入 */

		if(buffer1[jj][0] != NULL){					/*次のデータの確認*/
			sprintf(data1.comma1,"%c",comma1);			/*次のデータがあった場合カンマを入れる*/			
			sprintf(data1.name2,"%s",buffer1[jj++]);/*商品名を挿入*/
		}
			if(buffer1[jj][0] != NULL){					/*次のデータの確認*/
				sprintf(data1.comma2,"%c",comma1);			/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer1[jj++]);/*商品名を挿入*/
			}


		fputs(data1.name1,fp2);/*商品名をファイルへ出力*/
		fputs(data1.comma1,fp2);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name2,fp2);/*商品名またはスペースをファイルへ出力*/
		fputs(data1.comma2,fp2);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name3,fp2);/*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp2);			/*改行をファイルへ出力*/

		}

	fputs(fp2,"%d",jj);	/*品種数を出力ファイル1へ出力*/

	fclose(fp2);		/*ファイルを閉じる*/

	
	

		fp3 = fopen("list2.txt","w"); 
		if( fp3 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}
	
	
	for(kk=0;buffer2[kk][0]!=NULL;){	/*データが在るまで続ける*/
		
		sprintf(data1.name1,"%s",buffer2[kk++]);/* 商品名を挿入 */

		if(buffer2[kk][0] != NULL)
		{					/*次のデータの確認*/
			sprintf(data1.comma1,"%c",comma2);			/*次のデータがあった場合カンマを入れる*/			
			sprintf(data1.name2,"%s",buffer2[kk++]);/*商品名を挿入*/
		}
		if(buffer2[kk][0] != NULL)
			{					/*次のデータの確認*/
				sprintf(data1.comma2,"%c",comma2);			/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer2[kk++]);/*商品名を挿入*/
			}

		fprintf(fp3,"%s",data1.name1);/*商品名をファイルへ出力*/
		fprintf(fp3,"%s",data1.comma1);/*カンマまたはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.name2);/*商品名またはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.comma2);/*カンマまたはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.name3);/*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp3);			/*改行をファイルへ出力*/
	}
		fprintf(fp3,"%d\n",kk);	/*品種数を出力ファイル1へ出力*/

	fclose(fp3);		/*ファイルを閉じる*/
	fclose(fp1);
	return (0);
}
以上、宜しくお願いいたします。

dic
記事: 658
登録日時: 14年前
住所: 宮崎県
連絡を取る:

Re: アドレスのアクセス違反について

#2

投稿記事 by dic » 14年前

コンパイルが通りません

コード:

            if(strcmp(a[ii].number, "1") == 0) /*部門コードの確認*/
            }else if(strcmp(a[ii].number,"2") == 0)
    fputs(fp2,"%d",jj); /*品種数を出力ファイル1へ出力*/
の3箇所です

SATOち

Re: アドレスのアクセス違反について

#3

投稿記事 by SATOち » 14年前

>>dicさん

ご指摘ありがとうございます。

コード:

if(strcmp(a[ii].number, '1') == 0) /*部門コードの確認*/
}else if(strcmp(a[ii].number,'2') == 0)
fprintf(fp2,"%d\n",jj);	/*品種数を出力ファイル1へ出力*/
以上の通り修正、致しましたが、アクセス違反メッセージが表示されてしまいます。
他に何か原因など御座いますでしょうか?

お手数お掛けして申し訳御座いません。

non
記事: 1097
登録日時: 14年前

Re: アドレスのアクセス違反について

#4

投稿記事 by non » 14年前

1,2は修正したことになっていません。strcmpについて調べましょう。

それより、何をしたいのか見えてきません。ファイルはどのような形式になっているのでしょうか?
freadを使っている理由が見えませんが、freadなら"rb"の方が良いと思いますし。
non

SATOち

Re: アドレスのアクセス違反について

#5

投稿記事 by SATOち » 14年前

non さんが書きました:1,2は修正したことになっていません。strcmpについて調べましょう。

それより、何をしたいのか見えてきません。ファイルはどのような形式になっているのでしょうか?
freadを使っている理由が見えませんが、freadなら"rb"の方が良いと思いますし。
>>non様

ありがとうございます。
ファイルは以下の通りとなっております。

*************************************************************************
1,菓子A,1,菓子B,1,菓子C
2,野菜A,2,野菜B,2,野菜C
1,菓子D,1,菓子E,2,野菜D
1,菓子F,1,菓子G,2,野菜E
1,菓子H,2,野菜F,1,菓子I
1,菓子J,1,菓子K,1,野菜G
**************************************************************************

このファイルを読み込み、部門コード毎にファイルを分割し、最後に商品数を出力する問題です。
なお、完成型のファイルのレイアウトは以下の通りです。
出力ファイル1
***************************************************************************
菓子A,菓子B,菓子C
菓子D,菓子E,菓子F
菓子G,菓子H,菓子I
菓子J,菓子K
11
****************************************************************************
出力ファイル2
************************************
野菜A,野菜B,野菜C
野菜D,野菜E,野菜F
野菜G
7
****************************************

説明不足で申し訳御座いませんでした。
strcmpについても再度、調べてみます。

SATOち

Re: アドレスのアクセス違反について

#6

投稿記事 by SATOち » 14年前

strcmpの件は以下の通り修正、致しました。

コード:

if((a[ii].number, "1") == 0) 						
}else if((a[ii].number,"2") == 0)
宜しく、お願いいたします。

アバター
さかまき
記事: 92
登録日時: 14年前

Re: アドレスのアクセス違反について

#7

投稿記事 by さかまき » 14年前

>if((a[ii].number, "1") == 0)
>}else if((a[ii].number,"2") == 0)
どういう意図の構文です?

くわえて
fread(&a[ii].name ,6,1,fp1); の後に
a[ii].name[6]=0x0; がないと strcpy(buffer1[count1],a[ii].name);的にまずいかも

non
記事: 1097
登録日時: 14年前

Re: アドレスのアクセス違反について

#8

投稿記事 by non » 14年前

入力するファイルですが、
1,菓子A,1,菓子B,1,菓子C
このように必ず、3つ分があるわけですね。
また、最初の番号は絶対1桁ですね。
そして、商品名は必ず6バイトである。

まず、freadの必要はないと思います。ファイルはテキストファイルではないのですか?
それなら、fscanfを使いましょう。

構造体ですが、comma1やcomma2のメンバーは必要ないですね。
構造体の設計を考え直してください。

strcmpを今度は使っていないようですが、やっぱり間違っています。
文字列と文字の違いが理解されてないようです。
non

SATOち

Re: アドレスのアクセス違反について

#9

投稿記事 by SATOち » 14年前

さかまき さんが書きました:>if((a[ii].number, "1") == 0)
>}else if((a[ii].number,"2") == 0)
どういう意図の構文です?

くわえて
fread(&a[ii].name ,6,1,fp1); の後に
a[ii].name[6]=0x0; がないと strcpy(buffer1[count1],a[ii].name);的にまずいかも
>>さかまき様
ありがとうございます。
>if((a[ii].number, "1") == 0)
>}else if((a[ii].number,"2") == 0)
こちらの意図は入力ファイルから構造体メンバに格納した部門番号を1か2かを判定するものです。

>fread(&a[ii].name ,6,1,fp1); の後に
>a[ii].name[6]=0x0; がないと strcpy(buffer1[count1],a[ii].name);的にまずいかも
無知で申し訳ありません。a[ii].name[6]=0x0;の意図はコピーする際に先頭アドレスを指し示さなければ、いけないという事でしょうか?

宜しくお願い致します。

SATOち

Re: アドレスのアクセス違反について

#10

投稿記事 by SATOち » 14年前

non さんが書きました:入力するファイルですが、
1,菓子A,1,菓子B,1,菓子C
このように必ず、3つ分があるわけですね。
また、最初の番号は絶対1桁ですね。
そして、商品名は必ず6バイトである。

まず、freadの必要はないと思います。ファイルはテキストファイルではないのですか?
それなら、fscanfを使いましょう。

構造体ですが、comma1やcomma2のメンバーは必要ないですね。
構造体の設計を考え直してください。

strcmpを今度は使っていないようですが、やっぱり間違っています。
文字列と文字の違いが理解されてないようです。
>>non様
ありがとうございます。
ファイル形式はテキストファイルです。
fscanfの読み込み、方法と構造体設計について再度、検討してみます。

>strcmpを今度は使っていないようですが、やっぱり間違っています。
>文字列と文字の違いが理解されてないようです。
申し訳ありません。数字を囲っているダブルコーテーションをシングルに変更しました。

コード:

>if((a[ii].number, '1') == 0) 
>}else if((a[ii].number,'2') == 0)
宜しく、お願い致します。

アバター
さかまき
記事: 92
登録日時: 14年前

Re: アドレスのアクセス違反について

#11

投稿記事 by さかまき » 14年前

SATOち さんが書きました: >if((a[ii].number, "1") == 0)
>}else if((a[ii].number,"2") == 0)
こちらの意図は入力ファイルから構造体メンバに格納した部門番号を1か2かを判定するものです。
nonさんご指摘の通りです↓
non さんが書きました: >strcmpを今度は使っていないようですが、やっぱり間違っています。
>文字列と文字の違いが理解されてないようです。
SATOち さんが書きました: >fread(&a[ii].name ,6,1,fp1); の後に
>a[ii].name[6]=0x0; がないと strcpy(buffer1[count1],a[ii].name);的にまずいかも
無知で申し訳ありません。a[ii].name[6]=0x0;の意図はコピーする際に先頭アドレスを指し示さなければ、いけないという事でしょうか?
strcpy (to , from) ; は、文字列from を to の先頭アドレスから fromの中にNULがくるまでコピーし続けます。
7バイト文字列 name[7] に対し、ファイルから6バイト分セットしていますが7バイト目は何も行っていないので
内容は不定です。
strcpy の終わりはNULが現れるまでなので、その後にある広大なメモリ空間をズンズン逝っちゃっても文句言えません。なので7バイト目にNULをセットしています。

SATOち

Re: アドレスのアクセス違反について

#12

投稿記事 by SATOち » 14年前

>>さかまき様
ありがとうございます。
ご指摘して頂いた点は、把握し修正を致しました。

コード:


			if((a[ii].number, '1') == 0) /*部門コードの確認*/
			{
				a[ii].name[6]=0x0;
				/*部門コード1*/
				strcpy(buffer1[count1],a[ii].name);/*部門コード1の商品名格納*/
				count1++;									/*次に格納する配列へ移動*/
			}else if((a[ii].number,'2') == 0)
			{
				a[ii].name[6]=0x0;
				/*部門コード2*/
				strcpy(buffer2[count2],a[ii].name);/*部門コード2の商品名格納*/
				count2++;	
また、何か御座いましたら、宜しくお願い致します。

アバター
さかまき
記事: 92
登録日時: 14年前

Re: アドレスのアクセス違反について

#13

投稿記事 by さかまき » 14年前

>こちらの意図は入力ファイルから構造体メンバに格納した部門番号を1か2かを判定するものです。

はっきりいいますと、まちがっています
if ( ch1 , '1' ) == 0 ) この判断は常に偽となります。
if ('1' == ch1) でOKです。

non
記事: 1097
登録日時: 14年前

Re: アドレスのアクセス違反について

#14

投稿記事 by non » 14年前

fscanfを勧めましたが、カンマ区切りなので、fgetcで1文字ずつ読み込むか、fgetsで1行ずつ読み込んだ方がわかりやすいですね。
fscanfで作るのは面倒だろうと思います。
non

SATOち

Re: アドレスのアクセス違反について

#15

投稿記事 by SATOち » 14年前

さかまき さんが書きました:>こちらの意図は入力ファイルから構造体メンバに格納した部門番号を1か2かを判定するものです。

はっきりいいますと、まちがっています
if ( ch1 , '1' ) == 0 ) この判断は常に偽となります。
if ('1' == ch1) でOKです。
>>さかまき様

度々、申し訳御座いません。
指摘して頂いた通り、if文の中身を修正しました所、構造体から二次元配列に部門ごとに格納することができました。
まだ、警告が幾つかあるので、自力でやってみます!
ありがとう御座いました。

SATOち

Re: アドレスのアクセス違反について

#16

投稿記事 by SATOち » 14年前

non さんが書きました:fscanfを勧めましたが、カンマ区切りなので、fgetcで1文字ずつ読み込むか、fgetsで1行ずつ読み込んだ方がわかりやすいですね。
fscanfで作るのは面倒だろうと思います。
度々、ありがとう御座います。
一度、fscanfで試みましたが、仰るとおりメンバ数や引数が多くなってしまいますね。
ご指摘して頂いた、1行ずつ読み込む方法(fgets)で試みてみようと思います。

また何か御座いましたら、宜しくお願い致します。

SATOち

Re: アドレスのアクセス違反について

#17

投稿記事 by SATOち » 14年前

度々、申し訳ございません。
皆様にご指摘頂いた点を修正し、リビルドすると同じような警告文が21件表示されてしまいます。

修正したソースコードは以下の通りでございます。

コード:



printfで実験しましたところ、111行目までは問題なく、ロードされているようです。リビルドすると以下のような警告文が表示されます。

************************************************************************************
1>------ すべてのリビルド開始: プロジェクト: matome_k.c, 構成: Debug Win32 ------
1>プロジェクト 'matome_k.c'、構成 'Debug|Win32' の中間出力ファイルを削除しています。
1>コンパイルしています...
1>a.c
1>d:\project\matome_k.c\matome_k.c\a.c(45) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(79) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\string.h(74) : 'strcpy' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(85) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\string.h(74) : 'strcpy' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(98) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(107) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(109) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(111) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(112) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(113) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(115) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(116) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(117) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(137) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(146) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(148) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(150) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(152) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(153) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(155) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています。
1>d:\project\matome_k.c\matome_k.c\a.c(157) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>d:\project\matome_k.c\matome_k.c\a.c(158) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。
1>リンクしています...
1>LINK : 前回のインクリメンタル リンクで D:\project\matome_k.c\Debug\matome_k.c.exe が見つからなかったか、ビルドされませんでした。フル リンクを行います。
1>マニフェストを埋め込んでいます...
1>ビルドログは "file://d:\project\matome_k.c\matome_k.c\Debug\BuildLog.htm" に保存されました。
1>matome_k.c - エラー 0、警告 21
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========
**************************************************************************************************************
警告文は~の宣言を確認してください。と間接参照レベルがintとvoid*で異なっていますの2点になります。
ネットや参考書を用いて、調べましたが、よくわかえりませんでしたので、こちらに重ねて質問させていただきます。

SATOち

Re: アドレスのアクセス違反について

#18

投稿記事 by SATOち » 14年前

↑のソースコードを張り忘れておりました。

以下になります。

コード:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 256
#define _CRT_SECURE_NO_WARNINGS





/*メインモジュール*/
int main (void)
{
	 

	struct	input{
		char	number;		/*部門コード*/
		char	comma1;		/*カンマ*/
		char	name[7];		/*商品名*/
		char	comma2;		/*カンマ*/
		}a[50];


	/*ファイルに出力するための構造体*/
	struct output{

	char	name1[7];	/*商品名*/
	char	comma1[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name2[7] ;	/*商品名*(予め固定長分の半角スペースで初期化)*/
	char	comma2[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name3[7];	/*商品名(予め固定長分の半角スペースで初期化)*/

	}data1;

	int ii =0,kk =0,jj =0;
	int count1 =0,count2=0; /*二次元配列の添え字に格納*/
	char buffer1[50][50],buffer2[50][50];
	char dummy[MAX];
	char	comma =',';			/*コンマ*/
	FILE	*fp1;
	FILE	*fp2;
	FILE	*fp3;

		

		fp1 = fopen("list_input.txt","r"); 
		if( fp1 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		 //エラー処理
		}

	
	
		//while(fread(&a[ii].number,1,1,fp1) != NULL){	/* 部門コードがある間データを読み込む */
			
			//fread(&a[ii].comma1,1,1,fp1);			/* カンマ */

			//fread(&a[ii].name,6,1,fp1);/* 商品名 */
			
			//fread(&a[ii].comma2,1,1,fp1);			/*カンマまたは改行*/
			
			while (fgets(dummy,MAX,fp1) != NULL){
			// memcpy関数でコピー
			memcpy(&a[ii].number,dummy,1);
			memcpy(&a[ii].comma1,dummy+1,1);
			memcpy(&a[ii].name,dummy+1,6);
			memcpy(&a[ii].comma2,dummy+6,1);





			
			if('1' == a[ii].number) /*部門コードの確認*/
			{
				a[ii].name[6]=0x0;
				/*部門コード1*/
				strcpy(buffer1[count1],a[ii].name);/*部門コード1の商品名格納*/
				count1++;									/*次に格納する配列へ移動*/
			}else if('2' == a[ii].number)
			{
				a[ii].name[6]=0x0;
				/*部門コード2*/
				strcpy(buffer2[count2],a[ii].name);/*部門コード2の商品名格納*/
				count2++;									/*次に格納する配列へ移動*/
			}else{
				printf("ERROR:判定不能な部門コードが検出されました。\n"); /*判定不能な部門コードが検出された場合、エラーメッセージを表示し強制終了する*/
				//exit(1);
			}


			ii++;									/*次のデータへ移動*/
		}

			

	fp2 = fopen("list1.txt","w"); 
		if( fp2 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}
	

		for(jj=0;buffer1[jj][0]!=NULL;){	/*データが在るまで続ける*/
		
		sprintf(data1.name1,"%s",buffer1[jj++]);/* 商品名を挿入 */

		if(buffer1[jj][0] != NULL){				/*次のデータの確認*/
			sprintf(data1.comma1,"%c",comma);			/*次のデータがあった場合カンマを入れる*/			
			sprintf(data1.name2,"%s",buffer1[jj++]);/*商品名を挿入*/
		}
			if(buffer1[jj][0] != NULL){					/*次のデータの確認*/
				sprintf(data1.comma2,"%c",comma);			/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer1[jj++]);/*商品名を挿入*/
			}


		fputs(data1.name1,fp2);/*商品名をファイルへ出力*/
		fputs(data1.comma1,fp2);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name2,fp2);/*商品名またはスペースをファイルへ出力*/
		fputs(data1.comma2,fp2);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name3,fp2);/*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp2);			/*改行をファイルへ出力*/

		}

	fprintf(fp2,"%d\n",jj);	/*品種数を出力ファイル1へ出力*/

	

	
	

		fp3 = fopen("list2.txt","w"); 
		if( fp3 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}
	
	
	for(kk=0;buffer2[kk][0]!=NULL;){	/*データが在るまで続ける*/
		
		sprintf(data1.name1,"%s",buffer2[kk++]);/* 商品名を挿入 */

		if(buffer2[kk][0] != NULL)
		{					/*次のデータの確認*/
			sprintf(data1.comma1,"%s",comma);			/*次のデータがあった場合カンマを入れる*/			
			sprintf(data1.name2,"%s",buffer2[kk++]);/*商品名を挿入*/
		}
		if(buffer2[kk][0] != NULL)
			{					/*次のデータの確認*/
				sprintf(data1.comma2,"%S",comma);			/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer2[kk++]);/*商品名を挿入*/
			}

		fprintf(fp3,"%s",data1.name1);/*商品名をファイルへ出力*/
		fprintf(fp3,"%s",data1.comma1);/*カンマまたはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.name2);/*商品名またはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.comma2);/*カンマまたはスペースをファイルへ出力*/
		fprintf(fp3,"%s",data1.name3);/*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp3);			/*改行をファイルへ出力*/
	}
		fprintf(fp3,"%d\n",kk);	/*品種数を出力ファイル1へ出力*/

		printf("完了");

	fclose(fp3);		/*ファイルを閉じる*/
	fclose(fp2);		/*ファイルを閉じる*/
	fclose(fp1);
	return (0);
}


ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: アドレスのアクセス違反について

#19

投稿記事 by ISLe » 14年前

#define _CRT_SECURE_NO_WARNINGS
はソースファイルの先頭に書いてください。

dic
記事: 658
登録日時: 14年前
住所: 宮崎県
連絡を取る:

Re: アドレスのアクセス違反について

#20

投稿記事 by dic » 14年前

011年6月06日(月) 18:29 のソースコードのレビューです

strcmp関数は、文字列を比較します
今回の部門コードは文字です
文字列と文字をC言語では違ってあつかいます

fputsは

コード:

int fputs( const char *string, FILE *stream );
とあり、フォーマット指定の文字列は指定できません(多分)
引数は2つまでしか受け取らないので3つ引数はとれません


===追加
ここらへんは解決してますね
ソースコードの貼り付けをミスしていたようなので遅れた形になりました

SATOち

Re: アドレスのアクセス違反について

#21

投稿記事 by SATOち » 14年前

ISLe さんが書きました:#define _CRT_SECURE_NO_WARNINGS
はソースファイルの先頭に書いてください。
>>ISLe様、ありがとうございます。ご指摘して頂いたとおり、修正しましたところ、警告はなくなりました。
ただ _CRT_SECURE_NO_WARNINGSの定義により抜本的解決に至ったと考えて宜しいのでしょうか?

SATOち

Re: アドレスのアクセス違反について

#22

投稿記事 by SATOち » 14年前

dic さんが書きました:011年6月06日(月) 18:29 のソースコードのレビューです

strcmp関数は、文字列を比較します
今回の部門コードは文字です
文字列と文字をC言語では違ってあつかいます

fputsは

コード:

int fputs( const char *string, FILE *stream );
とあり、フォーマット指定の文字列は指定できません(多分)
引数は2つまでしか受け取らないので3つ引数はとれません


===追加
ここらへんは解決してますね
ソースコードの貼り付けをミスしていたようなので遅れた形になりました
>>dic様
承知いたしました。こちらのミスでご迷惑をお掛けして申し訳ありませんでした。

box
記事: 2002
登録日時: 14年前

Re: アドレスのアクセス違反について

#23

投稿記事 by box » 14年前

本題と関係あるかどうかはわかりませんが、何だか勘違いされているようなので…。

buffer[何とか][かんとか]
というchar型と、
NULL
というポインターとを比較することは、根本的に誤っています。
お気づきでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: アドレスのアクセス違反について

#24

投稿記事 by ISLe » 14年前

SATOち さんが書きました:ただ _CRT_SECURE_NO_WARNINGSの定義により抜本的解決に至ったと考えて宜しいのでしょうか?
いえ、_CRT_SECURE_NO_WARNINGSはC4996の警告を止める効果しかありません。

あとは他の方が指摘されているとおり、きちんと文字と文字列を区別してください。

それから、初期化しない一時変数の初期値は不定なので、データを入れたところまでしかデータが入っていないと考えるのは正しくありません。
#バッファいっぱいまでデータが入ったときも問題があります。

かずま

Re: アドレスのアクセス違反について

#25

投稿記事 by かずま » 14年前

non さんが書きました: fscanfを勧めましたが、カンマ区切りなので、fgetcで1文字ずつ読み込むか、fgetsで1行ずつ読み込んだ方がわかりやすいですね。
fscanfで作るのは面倒だろうと思います。
fscanf で書けますよ。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    FILE *fp[3];  char name[7];  int code, count[3] = { 0 };

    fp[0] = fopen("list_input.txt", "r");
    if (!fp[0]) fprintf(stderr, "can't open input file\n"), exit(1);
    fp[1] = fopen("list1.txt", "w");
    if (!fp[1]) fprintf(stderr, "can't create output file\n"), exit(1);
    fp[2] = fopen("list2.txt", "w");
    if (!fp[2]) fprintf(stderr, "can't create output file\n"), exit(1);

    while (fscanf(fp[0], "%d%*c %6[^,\n]%*c", &code, name) == 2) {
        if (code == 1 || code == 2) {
            if (count[code]++)
                fputc(",\n"[count[code]%3==1], fp[code]);
            fputs(name, fp[code]);
        } else fprintf(stderr, "file format error\n"), exit(1);
    }
    fprintf(fp[1], "\n%d\n", count[1]);
    fprintf(fp[2], "\n%d\n", count[2]);
    fclose(fp[0]), fclose(fp[1]), fclose(fp[2]);
    return 0;
}

SATOち

Re: アドレスのアクセス違反について

#26

投稿記事 by SATOち » 14年前

box さんが書きました:本題と関係あるかどうかはわかりませんが、何だか勘違いされているようなので…。

buffer[何とか][かんとか]
というchar型と、
NULL
というポインターとを比較することは、根本的に誤っています。
お気づきでしょうか。
ありがとうございます。
ご指摘して頂いた、NULLをポインタで比較することについて、改めて参考書で調べてみると間違いに気づくことができました。
警告文の「~間接参照レベル」というのを解消することが出来ました!

SATOち

Re: アドレスのアクセス違反について

#27

投稿記事 by SATOち » 14年前

ISLe さんが書きました:
SATOち さんが書きました:ただ _CRT_SECURE_NO_WARNINGSの定義により抜本的解決に至ったと考えて宜しいのでしょうか?
いえ、_CRT_SECURE_NO_WARNINGSはC4996の警告を止める効果しかありません。

あとは他の方が指摘されているとおり、きちんと文字と文字列を区別してください。

それから、初期化しない一時変数の初期値は不定なので、データを入れたところまでしかデータが入っていないと考えるのは正しくありません。
#バッファいっぱいまでデータが入ったときも問題があります。
ありがとうございます。
文字列と文字の区別についても再度、勉強してみようと思います。

変数についてご指摘して頂いた、「データを入れたところまでしかデータが入っていないと考えるのは正しくありません。」というのは変数宣言時に余分に領域を確保するのは控えるという解釈でよろしいでしょうか?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: アドレスのアクセス違反について

#28

投稿記事 by ISLe » 14年前

SATOち さんが書きました:変数についてご指摘して頂いた、「データを入れたところまでしかデータが入っていないと考えるのは正しくありません。」というのは変数宣言時に余分に領域を確保するのは控えるという解釈でよろしいでしょうか?
いいえ、余分に確保した領域が空文字列に初期化されていることを期待してはいけないということです。

「/*データが在るまで続ける*/」とコメントされているところ。コードは間違っていますが、読み込んだ文字列をコピーした要素より後の要素は空であるつもりで終了条件を書かれていますね。
そのつもりで正しいコードを書いても、読み込んだ文字列をコピーしなかった分も空文字列ではないので、バッファを超えてしまいアクセス違反を起こします。

かずま

Re: アドレスのアクセス違反について

#29

投稿記事 by かずま » 14年前

かずま さんが書きました:fscanf で書けますよ。
fscanf の書式が分かりにくいようなので、"%1d,%6s%*c" に訂正します。
ただし、6バイトの商品名に空白が含まれていないことを仮定しています。

また、fputc による区切り文字の出力も分かりにくいようなので、次のように変更。

コード:

    if (count[code] % 3 == 1)
        fputc('\n', fp[code]);
    else
        fputc(',', fp[code]);
ところで、fscanf より fgetc や fgets で読み込んだほうが本当に分かりやすいのでしょうか?

non
記事: 1097
登録日時: 14年前

Re: アドレスのアクセス違反について

#30

投稿記事 by non » 14年前

スキャン集合指定子は慣れると便利だけど、初心者にはわかりにくと思いました。
元のプログラムがバイナリで読み込み、指定位置だけを取り込んでいましたので、
fgetsで配列に取り込んだ方が処理しやすいのかと。
non

SATOち

Re: アドレスのアクセス違反について

#31

投稿記事 by SATOち » 14年前

ISLe さんが書きました:
SATOち さんが書きました:変数についてご指摘して頂いた、「データを入れたところまでしかデータが入っていないと考えるのは正しくありません。」というのは変数宣言時に余分に領域を確保するのは控えるという解釈でよろしいでしょうか?
いいえ、余分に確保した領域が空文字列に初期化されていることを期待してはいけないということです。

「/*データが在るまで続ける*/」とコメントされているところ。コードは間違っていますが、読み込んだ文字列をコピーした要素より後の要素は空であるつもりで終了条件を書かれていますね。
そのつもりで正しいコードを書いても、読み込んだ文字列をコピーしなかった分も空文字列ではないので、バッファを超えてしまいアクセス違反を起こします。
>>ISLes様
ありがとうございます。
では、実際にコピーした要素以外の要素に’\0’を代入すれば、いいのでしょうか?
以下のコード追加しましたが、やはり、ゴミ値が格納されてしまいます。

コード:


	memset(&a,'\0',sizeof(a));
	memset(&buffer1,'\0',sizeof(buffer1));
	memset(&buffer2,'\0',sizeof(buffer2));
よろしくお願い致します。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: アドレスのアクセス違反について

#32

投稿記事 by ISLe » 14年前

SATOち さんが書きました:では、実際にコピーした要素以外の要素に’\0’を代入すれば、いいのでしょうか?
以下のコード追加しましたが、やはり、ゴミ値が格納されてしまいます。
空文字列判定する分には十分だと思いますけど、どちらにせよバッファいっぱいまでデータを読み込んだときは後続する空文字列が無くなるのでバッファを超えてアクセスしてしまう問題が残ります。
count1,count2に読み込んだデータの数をカウントしているのでそれを使ってはいかがでしょう。

ゴミ値はどのように確認されたのでしょう。

SATOち

Re: アドレスのアクセス違反について

#33

投稿記事 by SATOち » 14年前

ISLe さんが書きました:
SATOち さんが書きました:では、実際にコピーした要素以外の要素に’\0’を代入すれば、いいのでしょうか?
以下のコード追加しましたが、やはり、ゴミ値が格納されてしまいます。
空文字列判定する分には十分だと思いますけど、どちらにせよバッファいっぱいまでデータを読み込んだときは後続する空文字列が無くなるのでバッファを超えてアクセスしてしまう問題が残ります。
count1,count2に読み込んだデータの数をカウントしているのでそれを使ってはいかがでしょう。

ゴミ値はどのように確認されたのでしょう。
>>ISLe様
ありがとうございます。

ゴミ値は入力ファイルから商品名を構造体にに格納された際に、確認としてprintfで表示してみたところ商品名の後にゴミ値が確認されました。


読み込んだバッファの最終要素に’\0’を代入すれば、いいのでしょうか?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: アドレスのアクセス違反について

#34

投稿記事 by ISLe » 14年前

SATOち さんが書きました:ゴミ値は入力ファイルから商品名を構造体にに格納された際に、確認としてprintfで表示してみたところ商品名の後にゴミ値が確認されました。
読み込んだバッファの最終要素に’\0’を代入すれば、いいのでしょうか?
全体のコードを見ないとどこでゴミが入るのか分からないですね。

「バッファの最終要素」とはどういう意味で使ってますか?
連続した文字列データの終端に'\0'が必要なのですよ。

(追記)
いまさらですけど、以前まったく同じ質問があって、指導が入っているんですよね。

かずま

Re: アドレスのアクセス違反について

#35

投稿記事 by かずま » 14年前

コード:

            memcpy(&a[ii].name,dummy+1,6);
            memcpy(&a[ii].comma2,dummy+6,1);
商品名が入っているのは、dummy[1] からの 6バイトではなくて、
dummy[2] からの 6バイトですよ。これがゴミの原因でしょう。
comma2 も意図した値は入らないけど、これは使わないから無害。

SATOち

Re: アドレスのアクセス違反について

#36

投稿記事 by SATOち » 14年前

ご協力して頂いた方々へ

ご無沙汰しております。
皆様にご指導して頂いたお陰で、正常にプログラムを作成することが出来ました。感謝します。

本当にありがとうございました!

コード:


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 256

/*メインモジュール*/
int main (void)
{
	/*入力ファイルを格納する構造体*/
		struct	input{
		char	number;		/*部門コード*/
		char	comma1;		/*カンマ*/
		char	name[7];		/*商品名*/
		char	comma2;		/*カンマ*/
		}a[50];


	/*ファイルに出力するための構造体*/
	struct output{
	char	name1[7];	/*商品名*/
	char	comma1[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name2[7] ;	/*商品名*(予め固定長分の半角スペースで初期化)*/
	char	comma2[2];	/*カンマ(予め固定長分の半角スペースで初期化)*/
	char	name3[7];	/*商品名(予め固定長分の半角スペースで初期化)*/
	}data1;

	int ii =0,kk =0,jj =0;	/*添え字に使用*/
	int count1 =0,count2=0; /*二次元配列の添え字に格納*/
	char buffer1[100][50] ,buffer2[100][50];	/*部門コードを判定した後に格納する二次元配列*/
	char	comma =',';			/*コンマ*/
	char	sp1[] =" "; /*1バイト分のスペース*/
	char	sp6[] ="      "; /*6バイト分のスペース*/
	FILE	*fp1; 
	FILE	*fp2;
	FILE	*fp3;	


		/*入力ファイルオープン*/
		fp1 = fopen("list_input.txt","r"); 
		if( fp1 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		 //エラー処理
		}
//str
	/*構造体、2次元配列を'\0'で初期化*/
	memset(&a, 0x00, sizeof(a));
	memset(&data1, 0x00, sizeof(data1));
	memset(&buffer1, 0x00, sizeof(buffer1));
	memset(&buffer2, 0x00, sizeof(buffer2));
//end

		while(fread(&a[ii].number,1,1,fp1) > 0){	/* 部門コードがある間データを読み込む */
			fread(&a[ii].comma1,1,1,fp1);			/* カンマ */
			fread(&a[ii].name,6,1,fp1);				/* 商品名 */
			fread(&a[ii].comma2,1,1,fp1);			/*カンマまたは改行*/
			
			/*部門コードの確認*/
			if('1' == a[ii].number) /*部門コードを判定*/
			{
				a[ii].name[7]=0x0;
				/*部門コード1*/
				strcpy(buffer1[count1],a[ii].name); /*部門コード1の商品名格納*/
				count1++;	/*次に格納する配列へ移動*/
			}else if('2' == a[ii].number)
			{
				a[ii].name[7]=0x0;
				/*部門コード2*/
				strcpy(buffer2[count2],a[ii].name);/*部門コード2の商品名格納*/
				count2++;									/*次に格納する配列へ移動*/
			}else
			{
				printf("ERROR:判定不能な部門コードが検出されました。\n"); /*判定不能な部門コードが検出された場合、エラーメッセージを表示し強制終了する*/
				exit(1);
			}
			
			ii++;									/*次のデータへ移動*/
		}
			fclose(fp1);/*入力ファイルを閉じる*/

			/*出力ファイル1オープン*/
		
		fp2 = fopen("list1.txt","w"); 
		if( fp2 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}

		for(jj=0;strlen(buffer1[jj])!=0 ;){	/*データが在るまで出力用構造体に格納を続ける*/
		sprintf(data1.name1,"%s",buffer1[jj]);/* 商品名を挿入 */
			jj++;

			if(strlen(buffer1[jj]) != 0) /*次のデータの確認*/
			{
				sprintf(data1.comma1,"%c",comma);	/*次のデータがあった場合カンマを入れる*/			
				sprintf(data1.name2,"%s",buffer1[jj]);	/*商品名を挿入*/
			jj++;
		
			}else{ /*2列目以降に出力するデータが存在しない場合は空き領域に固定長分のスペースを代入・出力する*/
			strcpy(data1.comma1 , sp1);
			strcpy(data1.name2 , sp6);
			strcpy(data1.comma2 , sp1);
			strcpy(data1.name3 , sp6);
			}

			if(strlen(buffer1[jj]) != 0) /*次のデータの確認*/
			{					
				sprintf(data1.comma2,"%c",comma);	/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer1[jj]);	/*商品名を挿入*/
				jj++; /*次のデータに以降*/
			
			}else{ /*3列目に出力するデータが存在しない場合は開き領域に固定長分のスペースを代入・出力する*/
			strcpy(data1.comma2 , sp1); 
			strcpy(data1.name3 , sp6);
			}
			
		/*ファイルへ出力*/
		fputs(data1.name1,fp2); /*商品名をファイルへ出力*/
		fputs(data1.comma1,fp2); /*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name2,fp2); /*商品名またはスペースをファイルへ出力*/
		fputs(data1.comma2,fp2); /*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name3,fp2); /*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp2); /*改行をファイルへ出力*/

		}
	fprintf(fp2,"%-20d\n",jj);	/*品種数を出力ファイル1へ出力*/
	
	
	fclose(fp2);		/*ファイルを閉じる*/
	

	/*出力ファイル2オープン*/
		fp3 = fopen("list2.txt","w"); 
		if( fp3 == NULL) 
		{
			fprintf(stderr, "Error : File is not open \n");
			exit(1);
		// エラー処理
		}
	
	for(kk=0;strlen(buffer2[kk])!=0;){	/*データが在るまで続ける*/
		
		sprintf(data1.name1,"%s",buffer2[kk]);	/* 商品名を挿入 */
		kk++;
		if(strlen(buffer2[kk]) != 0)	/*次のデータの確認*/
		{					
			sprintf(data1.comma1,"%c",comma);	/*次のデータがあった場合カンマを入れる*/			
			sprintf(data1.name2,"%s",buffer2[kk]);	/*商品名を挿入*/
			kk++;
		}else{	/*2列目以降に出力するデータが存在しない場合は空き領域に固定長分のスペースを代入・出力する*/
			strcpy(data1.comma1 , sp1);
			strcpy(data1.name2 , sp6);
			strcpy(data1.comma2 , sp1);
			strcpy(data1.name3 , sp6);
		}
		if(strlen(buffer2[kk]) != 0) /*次のデータの確認*/
			{					
				sprintf(data1.comma2,"%c",comma);			/*次のデータがあった場合カンマを入れる*/
				sprintf(data1.name3,"%s",buffer2[kk]);/*商品名を挿入*/
				kk++;	
		}else{	/*3列目に出力するデータが存在しない場合は開き領域に固定長分のスペースを代入・出力する*/
			strcpy(data1.comma2 , sp1);
			strcpy(data1.name3 , sp6);
		}

		fputs(data1.name1,fp3);/*商品名をファイルへ出力*/
		fputs(data1.comma1,fp3);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name2,fp3);/*商品名またはスペースをファイルへ出力*/
		fputs(data1.comma2,fp3);/*カンマまたはスペースをファイルへ出力*/
		fputs(data1.name3,fp3);/*商品名またはスペースをファイルへ出力*/
		fputc('\n',fp3);			/*改行をファイルへ出力*/
	}
	
	fprintf(fp3,"%-20d\n",kk);	/*品種数を出力ファイル1へ出力*/


	
	fputc('\n',fp3);
	
	fclose(fp3);		/*ファイルを閉じる*/
	
	printf("完了\n");
	
	return (0);
}

アバター
さかまき
記事: 92
登録日時: 14年前

Re: アドレスのアクセス違反について

#37

投稿記事 by さかまき » 14年前

とりあえず動きましたが、ここからいろいろ突っ込んでもらった方が為になりますよ。
まずは
a[ii].name[7]=0x0;
はまずいです。いつからか6が7に変っています。一応アクセス違反してます。

閉鎖

“C言語何でも質問掲示板” へ戻る