我对使用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();
}
答案 0 :(得分:2)
您可以使用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");
}
有关更多详细信息,您可以阅读this文章。
答案 1 :(得分:1)
在所有情况下都只需使用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
,以使fread
仅在while
循环中完成。
其他提示:
对于gets
,请参见Why is the gets function so dangerous that it should not be used?
对于fflush(stdin);
,请参见Using fflush(stdin)
答案 2 :(得分:1)
标准库还提供了stat
和fstat
函数,可让您填写struct stat
来直接确定文件大小。 stat
采用文件路径和指向stuct stat
的指针(声明为自动存储是可以的),而fstat
采用整数文件描述符作为其参数。
使用stat
确定文件大小是否大于零,只需调用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
来确定所需的内容。