Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Чтение различных данных из текстового файла, разделенного точкой с запятой в C

Автор вопроса: Chris_45Ответов: 3

Как читать разные записи данных, разделенные точкой с запятой, в массив в C?

из текстового файла: текст 1; 12.25; Текст Два; 5; Текст Три; 1,253

fopen ...
for(i = 0; i < nrRecords; i++) {
fscanf(myFile, " %[^;];", myRecords[i].firstText);  /* Ok first text*/
fscanf(myFile, "%lf", &myRecords[i].myDouble1);     /* But goes wrong with first double */
fscanf(myFile, " %[^;];", myRecords[i].secondText);
fscanf(myFile, "%d", &myRecords[i].myInt1);
fscanf(myFile, " %[^;];", myRecords[i].thirdText);
fscanf(myFile, "%lf",&myRecords[i].myDouble2);
}
fclose...
  • Если вы прочитаете каждое поле как строку %[^;];, получите ли вы правильный текст (например, 12.25 во втором поле)? Andreas Brinck 01.12.2009
  • Нет, проблема в том, что я читаю его в structarray с фиксированными типами. Chris_45 01.12.2009
  • Я попробовал, и это сработало правильно. Можете ли вы показать определение структуры myRecord? bhups 01.12.2009
  • struct myRecord{ char text1[20]; двойная цена; символ текст2[30]; внутренний номер; символ текст3[30]; двойная цена2; }; Chris_45 01.12.2009
  • Как это может пойти не так? Почему вы не проверяете возвращаемое значение fscanf? 22.02.2010

cfiletextinput

Ответы

Ответ 1 · рейтинг 1 · Peter Cordes

Обычный совет - читать целые строки, а затем анализировать их с помощью sscanf, strtok или чего-то еще. Слишком легко потерять свое место во входном файле, если вы сканируете прямо из файла. (т. е. в первый раз, когда что-то не совпадает, вам нужен способ пропустить это, если вы не хотите просто прервать там.)

Ответ 2 · tomlogic

Я бы использовал fgets, чтобы прочитать строку из файла, strtok, чтобы разбить ее на точку с запятой, strcpy, чтобы скопировать строки, strtod, чтобы преобразовать в double и strtol, чтобы преобразовать в long (а затем преобразовать в целое число).

Или прочитайте строку и используйте конечный автомат для обхода каждого символа и выполнения правильной операции. Например, вы будете копировать каждый символ в firstText, пока не дойдете до точки с запятой, а затем использовать strtod, чтобы съесть двойную, пропустить точку с запятой, скопировать байты в secondText и т. д.

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

fscanf(myFile, " %[^;];%lf;%[^;];%d;%[^;];%lf",
    myRecords[i].firstText,
    &myRecords[i].myDouble1,
    myRecords[i].secondText,
    &myRecords[i].myInt1,
    myRecords[i].thirdText,
    &myRecords[i].myDouble2);

И, как упоминалось другими, проверьте возвращаемое значение fscanf.

Я предпочитаю читать строку за раз, чтобы одна плохая строка не испортила все последующие конверсии.

Ответ 3 · рейтинг -1 · bhups

Один из способов - использовать strtok. А затем введите результат в int или float.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы