簡體   English   中英

如何檢測文件中是否存在數據C文件處理

[英]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)

標准庫還提供statfstat函數,使您可以填充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... */
}

無論哪種方式,都可以使用seekstat來確定所需的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM