如何在c中将文本文件传递到数组中?
这里没有程序员…所以请容忍我。我试图将一个现有的文本文件传递到一个数组中,但是一旦我的主菜单加载了该文件中曾经存在的信息,即使我没有做任何更改,这些信息也会消失。它只是不保存信息。该程序应该允许用户创建新文件或更新和/或加载现有文件。关于如何解决这个问题有什么想法吗?谢谢大家!如何在c中将文本文件传递到数组中?,c,arrays,file,C,Arrays,File,这里没有程序员…所以请容忍我。我试图将一个现有的文本文件传递到一个数组中,但是一旦我的主菜单加载了该文件中曾经存在的信息,即使我没有做任何更改,这些信息也会消失。它只是不保存信息。该程序应该允许用户创建新文件或更新和/或加载现有文件。关于如何解决这个问题有什么想法吗?谢谢大家! char fileName[20] = ""; void loadEmployee() { FILE* fPtr; char singleLine[150]; if (strcmp(fileN
char fileName[20] = "";
void loadEmployee()
{
FILE* fPtr;
char singleLine[150];
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "r");
while (!feof(fPtr))
{
fgets(singleLine, 150, fPtr);
puts(singleLine);
}
fclose(fPtr);
}
void saveEmployee()
{
FILE* fPtr;
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "w");
for (int i = 0; i < numEmps; i++)
{
fprintf(fPtr, "%s %f %f\n", emps[i].emps.name,
emps[i].emps.rate, emps[i].emps.hours);
}
fclose(fPtr);
}
void loadMenu()
{
int i = 0;
printf("1. Load from a file \n");
printf("2. Keyboard \n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: loadEmployee();
break;
default:
break;
}
do
{
printf("\nMAIN MENU\n");
printf("1.Add Employee\n");
printf("2.Edit Employee\n");
printf("3.Print Employee\n");
printf("4.Print ALL employees\n");
printf("5.Exit\n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: NameInput();
break;
case 2: printf("Choose employee: \n");
for (int i = 0; i < numEmps; i++)
{
printf("%d. %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
empUpdate(choice - 1);
break;
case 3: printf("Choose employee: \n\n");
for (int i = 0; i < numEmps; i++)
{
printf("%d) %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
printf("%s \n", emps[choice -
1].emps.name);
printf("%.2f \n", emps[choice -
1].emps.hours);
printf("%.2f \n", emps[choice -
1].emps.rate);
break;
case 4: PayOutput();
break;
case 5: printf("Quitting program!");
saveEmployee();
return;
default: printf("Invalid choice try again \n\n");
break;
}
} while (choice != 5);
}
int main()
{
struct information empsi[20];
loadMenu();
}
char文件名[20]=“”;
void loadEmployee()
{
文件*fPtr;
字符单线[150];
如果(strcmp(文件名“”)==0)
{
printf(“\n文件名是什么?”);
扫描文件(“%s”,文件名,20);
}
fopen_s(&fPtr,文件名,“r”);
而(!feof(fPtr))
{
fgets(单线,150,fPtr);
puts(单线);
}
fclose(fPtr);
}
void saveEmployee()
{
文件*fPtr;
如果(strcmp(文件名“”)==0)
{
printf(“\n文件名是什么?”);
扫描文件(“%s”,文件名,20);
}
fopen_s(&fPtr,文件名,“w”);
对于(int i=0;i
您的函数loadEmployee
只写入函数本地的字符[](这意味着它在最后被丢弃)
当程序退出时,您通过在write模式下重新打开文件来«保存»员工,该模式将清除该文件,随后的操作可能不会起到多大作用,因此该文件保持为空
尝试在函数外部实际返回或存储文件中的数据,以便以后可以重用。正如@hugo所说,程序读取文件,但不存储内容。这意味着
emp
将为空。退出时,打开文件进行写入并删除其内容。因为empemps
为空,所以不写入任何内容
这可以通过阅读类似于你写作的内容来解决。我不知道emps的确切样子,但类似的东西
for( numEmps = 1; fgets(singleLine, 150, fPtr); numEmps++ ) {
// I'm assuming emps is preallocated.
struct Employee emp = emps[numEmps-1];
sscanf(singleLine, "%80s %f %f",
emp.emps.name,
&emp.emps.rate,
&emp.emps.hours
);
}
注意,我查看的不是feof
而是fgets
的返回值。当你读台词的时候
代码中的其他问题 您没有检查文件是否已实际打开
fopen_s(&fPtr, fileName, "r");
if( !fPtr ) {
perror(fileName);
exit(1);
}
代码使用了很多全局变量。这导致了难以理解的代码,因为任何东西都可以随时更改这些全局变量。相反,利用函数参数和返回值。然后,您可以通过查看函数来完全理解它
例如,loadEmployee
应该获取要填充的结构和要读取的文件名,然后返回读取的数量<代码>保存员工与此类似
int loadEmployee(struct Employee *emps, char *fileName) {
...
return numEmps;
}
void saveEmployee(struct Employee *emps, char *fileName) {
...
}
两者都不应负责向用户询问文件名。这应该由调用方处理。功能应该做一件事;它使它们更简单、更灵活
我们可以移动逻辑,将文件名放入函数中。我们使用的不是全局的,而是全局的。此变量仍然是函数的局部变量,但不会重置getFileName
记住文件名
char *getFileName() {
static char fileName[80] = "";
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf("%20s", fileName);
}
return fileName;
}
...
switch(choice) {
case 1:
numEmps = loadEmployee(emps, getFileName());
break;
...
case 5:
printf("Quitting program!");
saveEmployee(emps, getFileName());
return;
}
...
这些不是问题的根源,但它们有助于构建代码,使其更易于理解和调试。为什么要使用Microsoft非标准函数
scanf_s
和fopen_s
?如果我不使用安全版本,可能会重复使用visual studio,它抛出了一个错误。请查看我的答案以消除错误。加载时,您似乎没有对单线
中包含的数据执行任何操作,可能您想使用fscanf
而不是fgets
。感谢您提供的所有反馈。我一定会实施这个。现在,我尝试添加您的代码,但是emp
不起作用,它抛出此错误不允许使用不完整类型。我不应该把这个添加到索引中吗?就像我使用的saveEmployee
<代码>fprintf(fPtr,”%