我正在嘗試將結構寫入檔案。我已經完成了定義結構的部分,我從檔案中讀取文本,然后將其保存在結構中,現在我想在結構中進行更改:students[i].name然后我希望將更改反映(寫入)在檔案中但它的編碼無效。
file.txt具有以下結構:
U,Virat Kohli,Virat Kohli,
U,Serena Williams,Virat Kohli,
G,Wayne Gretzky,Virat Kohli,
U,Virat Kohli,Virat Kohli,
U,Serena Williams,Virat Kohli,
G,Wayne Gretzky,Virat Kohli,
這是我的代碼:
#include <stdio.h>
#include <string.h>
typedef struct
{
// members for the student's type, name, surname
char type;
char name[50];
char surname[50];
} Student;
int main(void)
{
// for comparing strcmp
int result;
// file pointer variable for accessing the file
FILE *file;
// attempt to open file.txt in read mode to read the file contents
file = fopen("file.txt", "r");
// if the file failed to open, exit with an error message and status
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
// array of structs for storing the Student data from the file
Student students[100];
// read will be used to ensure each line/record is read correctly
int read = 0;
// records will keep track of the number of Student records read from the file
int records = 0;
// read all records from the file and store them into the students array
while (fscanf(file, " %c , I[^,], I[^,],", &students[records].type, students[records].name, students[records].surname) == 3)
{
// if fscanf read 3 values from the file then we've successfully read
records ;
// if there was an error reading from the file exit with an error message
// and status
if (ferror(file))
{
printf("Error reading file.\n");
return 1;
}
}
// close the file as we are done working with it
fclose(file);
// print out the number of records read
printf("\n%d records read.\n\n", records);
// print out each of the records that was read
for (int i = 0; i < records; i )
printf("%c %s %s\n",
students[i].type,
students[i].name,
students[i].surname);
printf("\n");
// change first record's name to Elena Heis
for (int i = 0; i < 1; i )
{
if (students[i].name == students[i].name)
{
printf("%s\n",
students[i].name);
strcpy(students[i].name, "Elena Heis");
printf("%s\n",
students[i].name);
}
}
// write changes to file
file = fopen("file.txt", "wb");
if (file != NULL)
{
fwrite(students, sizeof(Student), 1, file);
fclose(file);
}
return 0;
}
在寫入檔案像這樣破壞編碼之后

它應該是

uj5u.com熱心網友回復:
您的代碼是干凈的并且您的格式字串幾乎是完美的,但不建議使用決議csv檔案(或一般的任何檔案),fscanf()因為很難從錯誤中恢復,并且換行符與其他空白字符幾乎無法區分。特別是,\n格式字串末尾的 將匹配任何可能為空的空白字符序列。
測驗ferror()和feof()你所做的似乎很好,但不足以確保可靠的決議:如果fscanf()回傳一個短代碼,例如因為一個空欄位,決議將從有問題的行的中間繼續,ferror()也feof()不會導致回圈結束。
相反,您應該一次讀取一行fgets()并使用sscanf()來決議該行。
另請注意以下備注:
csv檔案似乎不包含
name和surname欄位,而是包含對手的全名。該檔案似乎
,在第三個欄位之后有尾隨。如果這是預期的,則確保記錄有效性的格式字串應更改為"%c,I[^,],I[^,\n]%1[,\n]"您應該檢查
records < 100以避免緩沖區溢位。測驗
if (students[i].name == students[i].name)是無用的,總是正確的。無需測驗即可更改第一個學生的姓名。您不能使用 撰寫文本檔案
fwrite(students, sizeof(Student), 1, file),而應使用fprintfas 作為終端的輸出。
這是修改后的版本:
#include <errno.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
// members for the student's type, name, surname
char type;
char name[50];
char surname[50];
} Student;
int main(void)
{
// file pointer variable for accessing the file
FILE *file;
// attempt to open file.txt in read mode to read the file contents
file = fopen("file.txt", "r");
// if the file failed to open, exit with an error message and status
if (file == NULL)
{
fprintf(stderr, "Error opening file %s for reading: %s\n", "file.txt", strerror(errno));
return 1;
}
// array of structs for storing the Student data from the file
Student students[100];
// length of the students array
int nrecords = sizeof(students) / sizeof(*students);
// buffer to read one line at a time
char buffer[256];
// records will keep track of the number of Student records read from the file
int records = 0;
// read all records from the file and store them into the students array
while (records < nrecords && fgets(buffer, sizeof buffer, file))
{
// Read a line/record from the file
// if it was able to read successfully which we expect read will be 3
char newline[3]; // for characters at end of line: `,\n` or `\n`
char extra; // to ensure no more characters are present
// there are 5 conversion specifiers, but sscanf should parse
// exactly 4 fields, including the trailing `,` and the newline
int read = sscanf(buffer,
"%c,I[^,],I[^,\n]%2[,\n]%c",
&students[records].type,
students[records].name,
students[records].surname,
newline, &extra);
// if fscanf read 3 values and a newline from the file then we've successfully read
// in another record
if (read == 4) {
records ;
} else {
fprintf(stderr, "invalid record: %s", buffer);
}
}
// if there was an error reading from the file exit with an error message
// and status
if (ferror(file))
{
fprintf(stderr, "Error reading file: %s\n", strerror(errno));
fclose(file);
return 1;
}
// close the file as we are done working with it
fclose(file);
// print out the number of records read
printf("\n%d records read.\n\n", records);
// print out each of the records that was read
for (int i = 0; i < records; i )
{
printf("%c %s %s\n",
students[i].type,
students[i].name,
students[i].surname);
}
printf("\n");
// change first record's name to Elena Heis
strcpy(students[0].name, "Elena Heis");
printf("%s\n", students[0].name);
// write changes to file
file = fopen("file.txt", "w");
if (file == NULL)
{
fprintf(stderr, "Error opening file %s for writing: %s\n", "file.txt", strerror(errno));
return 1;
}
// print out each of the records that was read
for (int i = 0; i < records; i )
{
fprintf(file, "%c,%s,%s,\n",
students[i].type,
students[i].name,
students[i].surname);
}
fclose(file);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/532246.html
標籤:C扫描
