Сканирование из файлов - PullRequest
1 голос
/ 09 мая 2011

Я сейчас пытаюсь отсканировать одну строку из файла, но у меня есть цепочка строк. Это пример строки, по которой мой профессор сказал мне работать.

enum status{MEM,PREP,TRAV}
union type { double int day, char* title, float cost}

13953 P 12 26 2011 1 5 2012 2 A 3.30 249.00 A 2.0 148.00 MEM Cuba Christmas 3 0 2 Sierra Del Rosario, Cuba

Я в порядке со всем, что принимается в момент (MEM Cuba Christmas), когда я сканирую его из ФАЙЛА. Я прочитал первую часть данных, используя только fscanf(), но MEM - это перечислимый тип с объединяющим типом, который определяет следующий ввод. Моя проблема с синтаксисом сканирования. Я попытался использовать getline, начиная с MEM, но я нажал на загвоздках с помощью токенизации, поскольку в городе / стране могут быть пробелы. Не уверен, какие другие сканы использовать, я смотрел на sscanf(), но не был уверен, работает ли он с файлами.

ОБНОВЛЕНИЕ:

int main(void);
{
 int m, length = 100;
 char *word, file_name[100];
 FILE *file_point
 printf("Please enter file name with .txt extension:");
 scanf("%s", file_name);
 file_point = fopen(file_name,"r");

  while (fscanf(file_point, "%d", &m) != EOF)
  {

  temp.dest_code = m;
  fscanf(file_point, " %c %d %d %d %d %d %d %d",
     &temp.area_code,
     &temp.Smonth, &temp.Sday, &temp.Syear,
     &temp.Emonth, &temp.Eday, &temp.Eyear,
     &temp.leg_num);
  for (n=0; n < temp.leg_num; n++)
    {
      fscanf(file_point," %c %f %f",
         &temp.tleg[n].travel_type,
         &temp.tleg[n].travel_time,
         &temp.tleg[n].cost);
    }
  fscanf(file_point," %d %d %d ",
     &temp.adult,
     &temp.child,
     &temp.infant);


  temp_name = (char *)malloc(length + 1);
  getline (&temp_name, &length, file_point);

  word = strtok(temp_name, ",");

  temp.dest_name=(char *)malloc(strlen(word)+1);
  strcpy(temp.dest_name, word);

  word = strtok(NULL, ",");

  temp.dest_country=(char *)malloc(strlen(word)+1);
  strcpy(temp.dest_country,word2);

  printf("name:%s country:%s\n", temp.dest_name, temp.dest_country);
      printf("adult:%d , child:%d , infant:%d \n", temp.adult, temp.child, temp.infant);

   }
}

Это был код, который я использовал в качестве основы, которую я придумал, но не знал, как обращаться с перечислимым и объединением. Я думал сделать что-то вроде:

getline(&status, &length, file_point);

но как мне преобразовать строку в целое или с плавающей точкой?

Ответы [ 2 ]

2 голосов
/ 09 мая 2011

Если я правильно понимаю вашу проблему (я не уверен, что понимаю), то вы столкнетесь с проблемой представления «MEM» (или «PREP» или «TRAV») как строки во входных данных, и вам придетсяпонять, как обрабатывать следующие данные.enum предполагает, что вы можете преобразовать строку MEM в значение MEM в перечислении.

Трудно полностью автоматизировать такое преобразование.Было бы проще просто распознать строки и решить, что делать на основе строки:

if (strcmp(found_string, "MEM") == 0)
    ...do the MEM stuff...
else if (strcmp(found_string, "PREP") == 0)
    ...do the PREP stuff...
else if (strcmp(found_string, "TRAV") == 0)
    ...do the TRAV stuff...
else
    ...report unknown type code...

Однако вы можете создать структуру для обработки преобразования строки в значение перечисления.

struct StateConv
{
     const char *string;
     enum state  number;
};

static struct StateConv converter[] =
{
    { "MEM",  MEM  },
    { "PREP", PREP },
    { "TRAV", TRAV },
};
enum { NUM_STATECONV = sizeof(converter) / sizeof(converter[0]) };

enum state state_conversion(const char *string)
{
    for (int i = 0; i < NUM_STATECONV; i++)
    {
        if (strcmp(string, converter[i].string) == 0)
            return(converter[i].number);
    }
    fprintf(stderr, "Failed to find conversion for %s\n", string);
    exit(1);
}

Вам нужна лучшая стратегия обработки ошибок, чем «выход при ошибке».

Ваш код сканирования должен прочитать слово и затем вызвать state_conversion().Затем, в зависимости от того, что вы получите, вы можете прочитать оставшиеся (следующие) данные в правильном порядке для вашего состояния.

1 голос
/ 09 мая 2011

Нет, вы не можете делать это так, как пытаетесь.MEM в вашем файле является строковым типом, вам нужно проанализировать его, как будто вы анализируете строку, а затем установить значение вашего перечисления в соответствии с этой строкой.Например, если вы хотите проанализировать ваш тип состояния (MEM, PREP, TRAV):

char typeBuffer[6];
fscanf(file_point,"%5s",typeBuffer);

Затем вручную сравните содержимое typeBuffer:

status stat;
if (strcmp(typeBuffer, "MEM") == 0){
     stat = MEM;
}

Преобразование между строковым типоми enum не может быть неявным.

...