Как fscanf () работает с двойными значениями? - PullRequest
0 голосов
/ 29 сентября 2018

В этом вопросе моя цель - понять поведение fscanf() при работе со значениями типа double.Язык - C.

Итак, мне пришлось читать числа в файле и сохранять их в массиве.Файл выглядит так:

1600 1 2 3 4 5 1700 6 7 8 9 10 1800 11 12 13 14 15

Мне нужны только эти цифры: 1660, 1700 и 1800 (J = 3).И у меня есть пять чисел между ними (I = 5).

Если я пытаюсь получить эти числа как целые числа, работает следующий код:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char filename[100];
    int *P; 
    int J = 3;
    int I = 5;  
    P = (int*)malloc(sizeof(int) * J);

    FILE *input_file;   
    iput_file = fopen("test.txt", "r");
    if (input_file == NULL) {
        fprintf(stderr, "Sorry, no such a file...\n");
        exit(1);
    }

    for (int j = 0; j < J; j++) {
        fscanf(input_file, "%d", &P[j]);
        printf("%d ", P[j]);
        for (int skip = 0; skip < I; ++skip) {
            fscanf(input_file, "%d");
        }
    }
    return 0;
}

Однако, если я пытаюсь получитьих как double, вот так, это не работает:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char filename[100];
    double *P;  
    int J = 3;
    int I = 5;  
    P = (double*)malloc(sizeof(double) * J);

    FILE *input_file;   
    input_file = fopen("test.txt", "r");
    if (input_file == NULL) {
        fprintf(stderr, "Sorry, no such a file...\n");
        exit(1);
    }

    for (int j = 0; j < J; j++) {
        fscanf(input_file, "%lf", &P[j]);
        printf("%lf ", P[j]);
        for (int skip = 0; skip < I; ++skip) {
            fscanf(input_file, "%lf");
        }
    }
    return 0;
}

На самом деле, когда я запускаю его, у меня выводится 1600.000000, затем программа останавливается без ошибок, как будтоничего не пошло не так.

Подумав и проверив несколько часов, я придумал следующее решение.То есть поместите значения, которые мне не нужны, в переменную корзины.Затем, во втором для, я отредактировал fscanf в

fscanf(input_file, "%lf", &trash);

И он работал просто отлично.

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

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Как вы экспериментировали, fscanf(input_file, "%lf"); имеет неопределенное поведение.Чтобы пропустить значение, вы можете преобразовать его во временную переменную или использовать опцию подавления присваивания fscanf, заданную * после %:

fscanf(input_file, "%*lf");

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

0 голосов
/ 29 сентября 2018

Это:

fscanf(input_file,"%lf");

Неопределенное поведение, потому что у вас есть строка формата, которая приказывает компьютеру записать ... куда?Вы не дали ему места для написания!

Просто включите предупреждения как ошибки при компиляции, и такого рода недопустимый код никогда не скомпилируется, избавляя вас от всевозможных проблем:

gcc -Wall -Wextra -Werror

Или:

clang -Weverything -Werror
...