#c #enums #unions #scanf
#c #перечисления #объединения #scanf
Вопрос:
В настоящее время я пытаюсь отсканировать одну строку из файла, но у меня проблема со строками. Это пример строки, над которой мой профессор посоветовал мне поработать.
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
Меня устраивает все, что принимается в момент (например, Рождество на Кубе), когда я сканирую это из ФАЙЛА. Я прочитал первую часть данных, просто используя 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", amp;m) != EOF)
{
temp.dest_code = m;
fscanf(file_point, " %c %d %d %d %d %d %d %d",
amp;temp.area_code,
amp;temp.Smonth, amp;temp.Sday, amp;temp.Syear,
amp;temp.Emonth, amp;temp.Eday, amp;temp.Eyear,
amp;temp.leg_num);
for (n=0; n < temp.leg_num; n )
{
fscanf(file_point," %c %f %f",
amp;temp.tleg[n].travel_type,
amp;temp.tleg[n].travel_time,
amp;temp.tleg[n].cost);
}
fscanf(file_point," %d %d %d ",
amp;temp.adult,
amp;temp.child,
amp;temp.infant);
temp_name = (char *)malloc(length 1);
getline (amp;temp_name, amp;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:%sn", temp.dest_name, temp.dest_country);
printf("adult:%d , child:%d , infant:%d n", temp.adult, temp.child, temp.infant);
}
}
Это был код, который я использовал в качестве основы, который я придумал, но не уверен, как обращаться с перечисляемым и объединением. Я думал о том, чтобы сделать что-то вроде:
getline(amp;status, amp;length, file_point);
но как мне преобразовать строку в целое число или с плавающей точкой?
Комментарии:
1. Ах да, забыл упомянуть, что я сканирую эту единственную строку из файла
2. не могли бы вы опубликовать какой-нибудь код, чтобы показать нам, что вы пытались сделать с этого момента?
3.
enum
В конце нужна точка с запятой.union
Также нужна точка с запятой в конце, а запятые должны быть с запятой. Однако, если вы скомпилировали свой код, то проблема в том, что вы не скопировали и не вставили свой код.
Ответ №1:
Если я правильно понимаю вашу проблему (я не уверен, что понимаю), то вы сталкиваетесь с проблемой отображения ‘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 %sn", string);
exit(1);
}
Вам нужна лучшая стратегия обработки ошибок, чем «выход при ошибке».
Ваш код сканирования должен будет прочитать слово, а затем вызвать state_conversion()
. Затем, в зависимости от того, что вы получите обратно, вы можете прочитать оставшиеся (следующие) данные правильным образом для заданного вам состояния.
Комментарии:
1. ах, хорошо, я получал много ошибок, пытаясь обработать это как строку
Ответ №2:
Нет, вы не можете сделать это так, как пытаетесь. MEM в вашем файле имеет строковый тип, вам нужно проанализировать его, как вы анализируете строку, а затем установить значение вашего перечисления в соответствии с этой строкой. Например, когда вы хотите проанализировать тип вашего статуса (MEM, PREP, TRAV):
char typeBuffer[6];
fscanf(file_point,"%5s",typeBuffer);
Затем вручную сравните содержимое буфера типов:
status stat;
if (strcmp(typeBuffer, "MEM") == 0){
stat = MEM;
}
Преобразование между строковым типом и перечислением не может быть неявным.
Комментарии:
1.
typeBuffer
Один слишком мал для чтения ‘PREP’ или ‘TRAV’ — вам нужно как минимум 5 там, и, вероятно, больше, чтобы допускать ошибки. Было бы неплохо использовать"%5s"
и измерение 6; это позволяет вам отказаться от «ПЕРЕМЕЩЕНИЯ» без переполнения переменной.