繁体   English   中英

从C中的文件读取带空格的字符串

[英]Reading string with spaces from file in c

我有一个关于从文件读取包含空格的字符串的问题。 这是我的功能,该功能从文件读取数据并将其写入结构数组。 但是,如果第一个字符串的输入包含两个字符串以及它们之间的空格,则第一个字符串将进入第一个参数,第二个字符串将进入第二个参数。 如何以某种方式将文件中的行分开,以使必要的数据进入结构的指定字段? 谢谢!

void readFileToDiary(FILE* file, drivingDiary* diaryTemp){

    int i = 0;

    file = fopen("test.txt", "r");
    if (file == NULL)
        printf("\nError opening file!\n");
    else{
        while (!feof(file)){
            fscanf(file, "%s %s %d %s %s %d", diaryTemp[i].locationStart,
                diaryTemp[i].timeStart, &diaryTemp[i].odometerStart,
                diaryTemp[i].locationEnd, diaryTemp[i].timeEnd,
                &diaryTemp[i].odometerEnd);
            i++;
        }
    }
}

文件中的示例行包含:某个地方13:40 10000另一个地方14:45 10120

所以,

      "some place" -> first field of structure,
             13:40 -> second field,
             10000 -> third field,
"some other place" -> fourth field,
             14:45 -> fifth filed,
             10120 -> sixth field.

UPD工作版本在这里(无需fscanf()检查)!

void readFileToDiary(FILE* file, drivingDiary* diary){

    int i = 0;

    file = fopen("test.txt", "r");
    if (file == NULL)
        printf("\nError opening file!\n");
    else{
        while(fscanf(file, " %[a-zA-Z ]%[0-9:]%d %[a-zA-Z ]%[0-9:]%d%*[\n]",
                diary[i].locationStart,
                diary[i].timeStart,
                &diary[i].odometerStart,
                diary[i].locationEnd,
                diary[i].timeEnd,
                &diary[i].odometerEnd) != EOF)
            i++;        
        }
    }
}

由于开始和结束位置的空格数未知,因此使用scanf()方法将很复杂。 但是,可以使用更“古老”的方法来解析它。

"some place 13:40 10000 some other place 14:45 10120"

首先,将每条线视为包含两个“航路点”; “开始”和“结束”。 然后,使用单个“航路点”解析方法简化对各个航路点的解析。

"some place 13:40 10000", "some other place 14:45 10120"

因此,将有几种方法来构建“航点”解析器。 当我看着问题时,我不想开始使用空格字符作为分隔符。 我想找到其他起点。

每个航路点都包含一个“:”字符,因此我从此处开始。 我从':'字符离开,找到空格,并将空格转换为'\\ 0'字符串终止字符。 这就隔离了航路点的“位置”。

然后,从':'处继续,找到空格,并将空格转换为'\\ 0'字符串终止符。 这就隔离了航路点的“时间”。

使用strtoul()可以轻松隔离航路点的里程表部分。

我的代码如下:

/***************************************************************************
** Compiler setup
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

typedef struct DRIVING_WAYPOINT_S
   {
   char *location;
   char *time;
   long  odometer;
   } DRIVING_WAYPOINT_T;

typedef struct DRIVING_DIARY_S
   {
   DRIVING_WAYPOINT_T start;
   DRIVING_WAYPOINT_T end;
   } DRIVING_DIARY_T;

/***************************************************************************
** Parse a waypoint.
*/
int ParseRecord(
      char                *I__string,
      char               **_O_string,
      DRIVING_WAYPOINT_T  *I__waypoint
      )
   {
   int rCode=0;
   char *cp, *space;

   /* Parse location */
   cp=strchr(I__string, ':'); /* Find the first ocurrance of ':' */
   if(NULL == cp)
      {
      rCode=EINVAL;
      fprintf(stderr, "Parse error.  Time does not contain a ':'\n");
      goto CLEANUP;
      }

   space = cp;
   while(' ' != *space)
      --space;

   *space = '\0';
   I__waypoint->location = strdup(I__string);

   /* Parse time */
   cp = space + 1;
   space=strchr(cp, ' ');
   if(NULL == space)
      {
      rCode=EINVAL;
      fprintf(stderr, "Parse error.  No space following time\n");
      goto CLEANUP;
      }

   *space='\0';
   I__waypoint->time = strdup(cp);

   /* Parse odometer */
   cp = space+1;
   I__waypoint->odometer = strtol(cp, &cp, 10);
   while(' ' == *cp)
      ++cp;

   if(_O_string)
      *_O_string = cp;

CLEANUP:

   return(rCode);
   }

/*******************************************************************************
** Parse the diary file. 
*/
int ReadFileToDiary(
      FILE             *I__fp,
      DRIVING_DIARY_T **IO_diary,
      int              *IO_diaryEntries
      )
   {
   int rCode = 0;
   char line[255+1];

   for(;;)
      {
      DRIVING_DIARY_T *tmp;
      char *cp;

      /* Read the next line from the file. */
      errno=0;
      if(NULL == fgets(line, sizeof(line), I__fp))
         {
         if(feof(I__fp))
            break;

         rCode=errno;
         fprintf(stderr, "fgets() reports: %d.\n", errno);
         goto CLEANUP;
         }

      /* Expand the diary array for one more entry. */
      tmp=realloc(*IO_diary, ((*IO_diaryEntries)+1) * sizeof(DRIVING_DIARY_T));
      if(NULL == tmp)
         {
         rCode=ENOMEM;
         fprintf(stderr, "realloc() failed.\n");
         goto CLEANUP;
         }
      *IO_diary = tmp;
      memset(&(*IO_diary)[*IO_diaryEntries], '\0', sizeof(DRIVING_DIARY_T));

      /* Check for empty string. */
      if('\0' == *line)
         continue;

      /* Parse the 'start' waypoint. */
      rCode=ParseRecord(line, &cp, &(*IO_diary)[*IO_diaryEntries].start);
      if(rCode)
         {
         fprintf(stderr, "ParseRecord(start) reports: %d\n", rCode);
         goto CLEANUP;
         }

      /* Parse the 'end' waypoint. */
      rCode=ParseRecord(cp, NULL, &(*IO_diary)[*IO_diaryEntries].end);
      if(rCode)
         {
         fprintf(stderr, "ParseRecord(end) reports: %d\n", rCode);
         goto CLEANUP;
         }

      /* Increment the 'diary entries' counter. */
      (*IO_diaryEntries)++;
      }

CLEANUP:

   return(rCode);   
   }

/*******************************************************************************
** Free the diary array.
*/
int DiaryFree(
      DRIVING_DIARY_T *diary,
      int              diaryEntries
      )
   {
   int rCode=0;
   int nCnt;

   for(nCnt=0; nCnt<diaryEntries; ++nCnt)
      {
      free(diary[nCnt].start.location);
      free(diary[nCnt].end.location);
      free(diary[nCnt].start.time);
      free(diary[nCnt].end.time);         
     }

   free(diary);   

   return(rCode);
   }

/*******************************************************************************
** Program start.  
*/
int main()
   {
   int              rCode        = 0;
   FILE            *fp           = NULL;
   DRIVING_DIARY_T *diary        = NULL;
   int              diaryEntries = 0;
   int              nCnt;

   /* Open the data file. */
   errno=0;
   fp = fopen("test.txt", "r");
   if(NULL == fp)
      {
      rCode=errno;   
      fprintf(stderr, "fopen() failed.  errno:%d\n", errno);
      goto CLEANUP;
      }

    /* Parse the file into the dynamic diary array. */
    rCode=ReadFileToDiary(fp, &diary, &diaryEntries);
    if(rCode)
      {
      fprintf(stderr, "ReadFileToDiary() reports: %d\n", rCode);
      goto CLEANUP;
      }

    /* Print out the array. */
    for(nCnt=0; nCnt < diaryEntries; ++nCnt)
      {
      printf("[%d] %s %s %ld %s %s %ld\n",
         nCnt,
         diary[nCnt].start.location,
         diary[nCnt].start.time,
         diary[nCnt].start.odometer,
         diary[nCnt].end.location,
         diary[nCnt].end.time,
         diary[nCnt].end.odometer
         );
       }

CLEANUP:

   if(diary)
      DiaryFree(diary, diaryEntries);

   if(fp)
      fclose(fp);

   return 0;
   }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM