在C语言中,如何将文本文件的不同行保存到不同的变量
如何将文本文件中的不同行保存到不同数据类型的不同变量中;所有这些变量组成了一个结构(在我的示例中是一个包含以下内容的flight结构) 我想通过文本文件添加的信息示例如下在C语言中,如何将文本文件的不同行保存到不同的变量,c,file,file-io,C,File,File Io,如何将文本文件中的不同行保存到不同数据类型的不同变量中;所有这些变量组成了一个结构(在我的示例中是一个包含以下内容的flight结构) 我想通过文本文件添加的信息示例如下 111 NYC Monday 我显然想把单词NYC和Monday保存到一个char数组中,但我想把111保存到一个整数变量中 到目前为止我有 while (fscanf(flightInfo, "%s", tempName) != EOF) { fscanf(flightInfo, "%d\n", &tem
111
NYC
Monday
我显然想把单词NYC和Monday保存到一个char数组中,但我想把111保存到一个整数变量中
到目前为止我有
while (fscanf(flightInfo, "%s", tempName) != EOF)
{
fscanf(flightInfo, "%d\n", &tempNum);
flight.flightNumber = tempNum;
fscanf(flightInfo, "%s\n", tempName);
strcpy(flight.desination, tempName);
fscanf(flightInfo, "%s\n", tempName)
strcpy(flight.departDay, tempName);
}
假设flightInfo是指向文件名的指针,tempNum是一个整数,tempName是一个字符数组听起来你的思路是对的 像这样的东西怎么样:
#define MAX_FLIGHTS 100
...
struct Flight flights[MAX_FLIGHTS ];
int n_flights = 0;
...
while (!feof(fp) && (n_flights < MAX_FLIGHTS-1))
{
if (fscanf(fp, "%d\n", &flights[n_flights].flightNum) != 1)
error_handler();
if (fscanf(fp, "%29s\n", flights[n_flights].destination) != 1)
error_handler();
if (fscanf(fp, "%14s\n", flights[n_flights].departDay) != 1)
error_handler();
++n_flights;
}
...
#定义最多100个航班
...
结构航班[最大航班];
国际n_航班=0;
...
而(!feof(fp)和&(n_航班
增编:
根据Chux的建议,我修改了代码,通过将scanf max string length设置为29(比char[30]缓冲区大小小1),来减少潜在的缓冲区溢出
以下是更详细的解释:
您必须回答的第一个问题是:让人们或在其他平台上阅读文件有多重要 如果没有那么重要,那么我建议使用
fwrite()
和fread()
进行序列化。这更容易为每个记录编写代码,并且只要结构大小相同,就允许O(1)访问文件中的任何记录
如果您确实希望将它们存储为单独的行,那么从文件中读入行的最佳方法是使用fgets()
伪代码如下:
typedef struct flight {
int flightNum;
char desination[30];
char departDay[15];
} flight;
typedef struct flightSet {
flight *flights;
size_t n; /* number of flights */
size_t nAlloc; /* number of flights you have space for */
} flightSet;
#define FLIGHTSET_INIT_SIZE 16
#define MAX_LINE_LENGTH 128
#define FILENAME "file.txt"
// Create a new flightSet, calling it F
// Allocate FLIGHTSET_INIT_ALLOC number of flight structures for F->flights
// Set F->n to 0
// Set F->nAlloc to FLIGHTSET_INIT_ALLOC
/* Set up other variables */
size_t i = 0; // iterator */
char buffer[MAX_LINE_LENGTH]; // for reading with fgets() */
flights *temp; // for realloc()ing when we have more flights to read
// after reaching nAlloc flights
char *endptr; // for using strtol() to get a number from buffer
FILE *fp; // for reading from the file
// Open FILENAME with fp for reading
//MAIN LOOP
// If i == F->nAlloc, use realloc() to double the allocation of F->flights
// If successful, double F->nAlloc
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file
// Use break to get out of the main loop
}
F->flights[i]->flightNum = (int)strtol(buffer, &endptr, 10);
if (endptr == buffer) {
// The first invalid character that can't be converted to a number is at the very beginning
// of the buffer, so this is not a valid numerical character and your data file is corrupt
// Print out an error message
break;
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->destination = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->departDay = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
// If you've gotten here so far without errors, great!
// Increment F->n to reflect the number of successful records we have in F.
// Increment i, the loop iterator
//Final cleanup. Should include closing the file, and freeing any allocated
//memory that didn't end up in a valid record.
@约书亚-这不是个坏主意;使用并不是本质上的邪恶。我只是想尽可能地接近您的原始代码。请让我知道,如果你想让我更新我的例子;如果您还有任何问题,请告知我们。建议使用fscanf(fp,%29s\n),航班[n\u航班]。目的地)
而不是fscanf(fp,%s\n,航班[n\u航班]。目的地)
typedef struct flight {
int flightNum;
char desination[30];
char departDay[15];
} flight;
typedef struct flightSet {
flight *flights;
size_t n; /* number of flights */
size_t nAlloc; /* number of flights you have space for */
} flightSet;
#define FLIGHTSET_INIT_SIZE 16
#define MAX_LINE_LENGTH 128
#define FILENAME "file.txt"
// Create a new flightSet, calling it F
// Allocate FLIGHTSET_INIT_ALLOC number of flight structures for F->flights
// Set F->n to 0
// Set F->nAlloc to FLIGHTSET_INIT_ALLOC
/* Set up other variables */
size_t i = 0; // iterator */
char buffer[MAX_LINE_LENGTH]; // for reading with fgets() */
flights *temp; // for realloc()ing when we have more flights to read
// after reaching nAlloc flights
char *endptr; // for using strtol() to get a number from buffer
FILE *fp; // for reading from the file
// Open FILENAME with fp for reading
//MAIN LOOP
// If i == F->nAlloc, use realloc() to double the allocation of F->flights
// If successful, double F->nAlloc
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file
// Use break to get out of the main loop
}
F->flights[i]->flightNum = (int)strtol(buffer, &endptr, 10);
if (endptr == buffer) {
// The first invalid character that can't be converted to a number is at the very beginning
// of the buffer, so this is not a valid numerical character and your data file is corrupt
// Print out an error message
break;
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->destination = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->departDay = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
// If you've gotten here so far without errors, great!
// Increment F->n to reflect the number of successful records we have in F.
// Increment i, the loop iterator
//Final cleanup. Should include closing the file, and freeing any allocated
//memory that didn't end up in a valid record.