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

时间:2014-05-15 13:52:11

标签: c string file parsing file-io

我有一个关于从文件中读取包含空格的字符串的问题。 这是我的函数,它从文件中读取数据并将其写入结构数组。 但是,如果第一个字符串的输入包含两个字符串并且它们之间有空格,则第一个字符串转到第一个参数,第二个字符串转到第二个参数。 如何从文件中分割行,使必要的数据转到指定的结构字段? 谢谢!

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++;        
        }
    }
}

1 个答案:

答案 0 :(得分:3)

由于起始位置和结束位置的空格数未知,因此使用scanf()方法会很复杂。但是,它可以使用更多的旧学校进行解析。方法....

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

首先,将每一行视为包含两个'路径点&#39 ;; a'开始'和'结束'然后通过使用单个" way-point"来简化解析各个路点的过程。解析方法。

"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;
   }