Fscan со структурой

Я читаю из текстового файла, который содержит 3 столбца (идентификатор координаты, шнур x и шнур y). Все значения разделены табуляцией (\ t). Когда я пытаюсь использовать fscanf () для создания списка, он не печатает мою 1-ю строку и распечатывает последнюю строку 2 раза.

while ((fgets(buffer, BUFFER_SIZE, fptr)) != NULL)
{
    fscanf(fptr,"%d%f%f", &id, &xc, &yc);
    tempValue.xyID = id;
    tempValue.x = xc;
    tempValue.y = yc;
    addToList(nodeID++, tempValue);
}
printList();

Приведенный выше код не работает со scanf, но когда я это сделаю:

while ((fgets(buffer, BUFFER_SIZE, fptr)) != NULL)
{
    tempValue.xyID = atoi(strtok(buffer,"\t"));
    tempValue.x = atoi(strtok(NULL, "\t"));
    tempValue.y = atoi(strtok(NULL, "\t"));
    addToList(nodeID++, tempValue);
}
printList();

Приведенный выше код работает отлично, и я хочу знать, что я делаю не так с fscanf. Спасибо!

Вы забыли разделитель \t в вызове fscanf ...

ThiefMaster 27.10.2018 17:20

fscanf (fptr, "% d \ t% f \ t% f", & id, & xc, & yc); , попробовал это то же самое: /

Luka Roguljic 27.10.2018 17:22

Пожалуйста, предоставьте правильный минимальный воспроизводимый пример, включая а) введенные вами данные, б) полученные вами выходные данные и определение id, xc, ycа такжеtempValue.

Antti Haapala 27.10.2018 18:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
36
1

Ответы 1

Если вы используете fgets() для чтения строки из файла в память, вам нужно использовать sscanf(buffer, ...) для сканирования этой строки. Если вы вызываете fscanf(fptr, ...), вы в основном отбрасываете только что прочитанную строку и читаете следующий бит данных из файла.

Причина, по которой вы видите последнюю строку дважды, скорее всего, вызвана тем, что fscanf() был вызван, когда вы уже достигли конца файла. Если он не может прочитать какие-либо данные, переменные, которые вы передаете в fscanf(), не будут перезаписаны. Вы не проверяете возвращаемое значение fscanf(), чтобы убедиться, что вы действительно читаете новые данные, вместо этого вы всегда вызываете addToList(), который затем добавит элемент в список, используя значения, сохраненные предыдущим вызовом fscanf().

Вторая попытка работает, потому что теперь вы фактически анализируете данные, которые считываете в буфер. Обратите внимание, что вы снова не проверяете все возвращаемые значения функций, которые вы вызываете, на наличие ошибок. Если вы попытаетесь прочитать файл, содержащий строку с менее чем тремя элементами, тогда ваша вторая версия выйдет из строя, потому что strtok() вернет NULL, и тогда вы фактически вызовете atoi(NULL). Кроме того, atoi() молча игнорирует любые ошибки, например, когда строка, которую он пытается проанализировать, не содержит допустимого числа, и вместо этого возвращает 0. Лучше использовать strtol(), если вы хотите быть уверены, что вы правильно проанализировали значение. .

Спасибо за хороший ответ. Но почему он по-прежнему печатает последнюю строку 2 раза?

Luka Roguljic 27.10.2018 17:27

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

G. Sliepen 27.10.2018 17:29

Я заменил fscanf на sscanf, как вы сказали. Я больше не использую fscanf в программе

Luka Roguljic 27.10.2018 17:33

Большой. Убедитесь, что вы также проверили возвращаемое значение sscanf()!

G. Sliepen 27.10.2018 17:37

Другие вопросы по теме