iT邦幫忙

0

c 語言 file 問題

  • 分享至 

  • xImage

我最近剛學有關 c的file processing 所以寫了以下程式練習,但第二支程式一直出錯我不知道到底哪裡出錯了(我都有照原文書打啊?) ps:我的compiler是vc
第一支(建立dat檔)

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE *dataPtr;

	int i=0;
	char name[128]={0};
	int  id=0;
	char password[128]={0};
	int  balance=0;



	dataPtr=fopen("account.dat","w");
	for(i=1;i<=2;i++)
	{	
		printf("%-15s%-15s%-15s%-15s\n","請輸入戶名","請輸入帳號","請輸入密碼","請輸入存款");
		
		scanf("%s%d%s%d",name,&id,password,&balance);
		fprintf(dataPtr,"%s%d%s%d",name,id,password,balance);

	}
	fclose(dataPtr);

	



	return 0;
}

第二支程式(讀取第一支程式所產生的dat檔)

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

int main()
{
	FILE  *dataPtr;
	int i=0;

	char name[128]={0};
	int  id=0;
	char password[128]={0};
	int  balance=0;


	
	dataPtr=fopen("account.dat","r");

	printf("%-15s%-15s%-15s%-15s\n","戶名","帳號","密碼","存款");
	
	for(i=1;i<=2;i++)
	{
		fscanf(dataPtr,"%s%d%s%d",name,&id,password,&balance);
		   printf("%-15s%-15d%-15s%-15d\n",name,id,password,balance);
	}

	fclose(dataPtr);


	return 0;
}

以下為停止原因:
debug assertion failed!

program:c:\users\user\desktop\myATM\Debug\myATM.exe
File:f:\dd\vctools\crt_bld\self_x86\crt\fclose.c
Line:47
expression (stream!=NULL)

for information on how your program can cause an assertion failure,see the Visual
C++ documentation on asserts

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

4
bizpro
iT邦大師 1 級 ‧ 2012-09-12 22:56:24

錯誤的發生是因為第二支程式找不到account.dat, 是不是切換了目錄或改變了檔案的權限?

你的第一支程式, 我命名為addaccount.c並改了一個地方, 讓資料正確存入:
fprintf(dataPtr,"%s %d %s %d\n",name,id,password,balance);
你的第二支程式, 我命名為listaccount.c, 並無修改.

這是在ubuntu下的動作, 用的是gcc來編譯:
$ gcc -o addaccount addaccount.c
$ gcc -o listaccount listaccount.c

執行addaccount:
$ ./addaccount
請輸入戶名請輸入帳號請輸入密碼請輸入存款
account01 000001 1qaz2wsx 1000000
請輸入戶名請輸入帳號請輸入密碼請輸入存款
account02 000002 23fdwfsdfew 200000

列出account.dat內容:
$ cat account.dat
account01 1 1qaz2wsx 1000000
account02 2 23fdwfsdfew 200000

執行listaccount:
$ ./listaccount
戶名 帳號 密碼 存款
account01 1 1qaz2wsx 1000000
account02 2 23fdwfsdfew 200000

請問你改的地方是%s%d%s%d 中加空白嗎?
另外 要怎麼讓第二支程式讀到account.dat 是放到同一個資料夾嗎?

謝謝~

我的問題已經解決了~ 謝謝你的回答!

4
wwx
iT邦好手 1 級 ‧ 2012-09-14 08:09:22

問題在這邊吧!
fscanf(dataPtr,"%s%d%s%d",name,&id,password,&balance);
那個 %s 在抓 name 時就把資料取光了!!
可先試試
fscanf(dataPtr,"%s",name);
然後把 name 秀出來看是什麼, 就會知道意思了!
這邊也有個前提須注意,
就是name,id,password,balance的資料總長度不可超過name[128],
不然也是會掛掉!
有含字串抓取的部分不能這樣作

請問一下甚麼是 buf ? 謝謝!

wwx iT邦好手 1 級 ‧ 2012-09-16 23:46:05 檢舉

buf 就是宣告的
char buf[1024];
也就一個較大像 name 一樣的字串空間

但是我發現我看錯了~
寫檔的地方不是寫
printf("%-15s%-15d%-15s%-15d\n",name,id,password,balance);
而是寫
fprintf(dataPtr,"%s%d%s%d",name,id,password,balance);
所以並沒有所謂15個字元為欄位的依據
假設
name,id,password,balance 分別為 ABCD,XYZ,12345,66000
所以寫入檔案的方式為
fprintf(dataPtr,"%s%d%s%d",name,id,password,balance);
則檔案內容是
ABCDXYZ1234566000

當讀檔用
fscanf(dataPtr,"%s",buf);
則讀到 buf 的內容就是
ABCDXYZ1234566000
想要分出 name,id,password,balance 分別是 ABCD,XYZ,12345,66000 將無從依據

建議寫檔的地方可改為
fprintf(dataPtr,"%s,%d,%s,%d",name,id,password,balance);
也就是加入逗號當分隔點
則同樣的內如寫入與讀出時的內容變為
ABCD,XYZ,12345,66000
因此可以去讀一下 strtok 這個函數的用法,
透過以逗號作分隔, 由 buf 解出所要的 name,id,password,balance

我要發表回答

立即登入回答