Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中,如何将文本文件的不同行保存到不同的变量_C_File_File Io - Fatal编程技术网

在C语言中,如何将文本文件的不同行保存到不同的变量

在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

如何将文本文件中的不同行保存到不同数据类型的不同变量中;所有这些变量组成了一个结构(在我的示例中是一个包含以下内容的flight结构)

我想通过文本文件添加的信息示例如下

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.