[英]How to detect if there exists a data in a file C File Handling
我對使用C語言進行文件處理非常陌生。我想問一下是否有任何方法可以檢測文件中是否存在現有數據。 因為如果沒有,我將使用"wb"
,但是如果已經有數據,我將使用附加"ab"
。
寫入數據時,我嘗試使用"wb"
而不是"ab"
,但寫入的第一個數據無法讀取。
這是一個例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct clientInfo{
char Name[30];
};
void inputAccounts();
void viewAllRecords();
int main()
{
showOptions();
}
void inputData()
{
FILE *fp;
fp = fopen("hello", "ab");
struct clientInfo PERSONAL;
if(fp == NULL)
{
printf("Error!!!");
getch();
}
else
{
fflush(stdin);
printf("Enter Name: ");
gets(PERSONAL.Name);
fwrite((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
printf("File Created!!!");
getch();
fclose(fp);
}
}
void showOptions()
{
char choice;
system("cls");
printf("\n[1] Add Accounts");
printf("\n[2] View Records");
choice = getch();
if (choice == '1')
{
inputData();
}
else if (choice == '2')
{
viewAllRecords();
}
showOptions();
}
void viewAllRecords()
{
FILE *fp;
fp = fopen("hello", "rb");
struct clientInfo PERSONAL;
fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
system("cls");
if(fp == NULL){
printf("Error!!!");
getch();
}
else
{
while((fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp))==1)
{
printf("Name: %s\n", PERSONAL.Name);
}
}
getchar();
}
您可以使用fseek()
完成目標。 fseek()
用於將與給定文件關聯的文件指針移動到特定位置。
FILE *fp;
fp = fopen("test.txt", "r");
// Moving pointer to end
fseek(fp, 0, SEEK_END);
if(ftell(fp)>0){
printf("data exists on the file.\n");
}else{
printf("no data.\n");
}
有關詳細信息,你可以閱讀該文章。
在所有情況下都只需使用ab
。
如果文件已經存在,它將打開文件,並從文件末尾開始寫入。
如果不存在,將創建該文件,並從文件末尾開始寫入,該末尾與開頭相同。
從http://man7.org/linux/man-pages/man3/fopen.3.html :
a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.
編輯
由於OP發布了更多代碼,因此可以看出第一條記錄永遠不會被打印:
struct clientInfo PERSONAL;
fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
^^^^^^^
Read but there is no print
system("cls");
if(fp == NULL){
printf("Error!!!");
getch();
}
else
{
while((fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp))==1)
{
printf("Name: %s\n", PERSONAL.Name);
}
}
解決方案很簡單-只需刪除該fread
以便僅在while
循環中完成fread
。
其他提示:
有關gets
請參閱為什么gets功能如此危險,以至於不應使用它?
對於fflush(stdin);
請參閱使用fflush(stdin)
標准庫還提供stat
和fstat
函數,使您可以填充struct stat
來直接確定文件大小。 stat
使用文件路徑和指向stuct stat
的指針(聲明為自動存儲是可以的),而fstat
則使用整數file-descriptor作為其參數。
使用stat
確定文件大小是否大於零是一個簡單的事情, .st_size
調用stat
然后檢查.st_size
結構成員。
通過適當的驗證,您可以執行以下操作:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAXC 1024
int main (void) {
char fn[MAXC]; /* filename */
struct stat sbuf; /* stat buffer */
FILE *fp;
/* prompt, read filename, trim line-end */
fputs ("enter filename: ", stdout);
if (!fgets (fn, MAXC, stdin)) {
fputs ("(user canceled input)\n", stderr);
return 1;
}
fn[strcspn (fn, "\r\n")] = 0;
/* call stat, fill stat buffer, validate success */
if (stat (fn, &sbuf) == -1) {
perror ("error-stat");
return 1;
}
/* test sbuf.st_size to check if file size > 0 */
if (sbuf.st_size > 0) {
puts ("opened ab");
fp = fopen (fn, "ab");
}
else {
puts ("opened wb");
fp = fopen (fn, "wb");
}
/* rest of code... */
}
無論哪種方式,都可以使用seek
或stat
來確定所需的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.