KoshakSB
@KoshakSB
студент ггту сухого

Как избавить от заданных размеров количества строк и столбцов при считывании из файла?

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

#include <graphics.h>
#include <stdio.h>
#include <locale.h>

#include "bibliot.h"
//можно double
#define MAX_ROWS 102
#define MAX_COLS 3

int main(int argc, char** argv) {
	setlocale(LC_ALL, "Russian");
    int gd = DETECT, gm;
    initgraph(&gd, &gm, NULL);
    
    
    //  размеры графика и положение осей координат
    int leftMargin = 100, topMargin = 50;
    int width = 500, height = 3000;
    int xAxisLength = 400, yAxisLength = 200;
    int xAxisPos = leftMargin, yAxisPos = topMargin + yAxisLength;

   // Отрисовка оси абсцисс (X)
    line(0, getmaxy() / 2, getmaxx(), getmaxy() / 2);
    // Отрисовка оси ординат (Y)
    line(getmaxx() / 2, 0, getmaxx() / 2, getmaxy());

    // Подписи осей
    outtextxy(getmaxx() - 50, getmaxy() / 2 + 10, "X");
    outtextxy(getmaxx() / 2 + 10, 10, "Y");


    
FILE *f;
    char data[MAX_ROWS][MAX_COLS][102];
    int rows = 0;
    float orders[MAX_ROWS]; // Массив для количеств заказов, теперь тип float
    float income[MAX_ROWS]; // Массив для суммы дохода, теперь тип float

    f = fopen("predpriyatiya.txt", "rt");
    if (f == NULL) {
        printf("Не удалось открыть файл.\n");
        return 1;
    }

    // Чтение данных из файла
    while (rows < MAX_ROWS && fscanf(f, "%[^;];%[^;];%[^\n]", data[rows][0], data[rows][1], data[rows][2]) == 3) {
        // Запись данных в массивы
        orders[rows] = atof(data[rows][1]); // Преобразование строки в float и запись в массив заказов
        income[rows] = atof(data[rows][2]); // Преобразование строки в float и запись в массив доходов
        rows++;
    }

    fclose(f);
            // Нахождение максимального значения дохода
    float maxIncome = 0;
    for (int i = 0; i < rows; i++) {
        if (income[i] > maxIncome) {
            maxIncome = income[i];
        }
    }

    // Отметьте точки на графике для значений income
    for (int i = 0; i < rows; i++) {
        int x = xAxisPos + (int)((orders[i] / MAX_ROWS) * xAxisLength);
        int y = yAxisPos - (int)((income[i] / maxIncome) * yAxisLength);
        putpixel(x, y, WHITE);
    }
    // Нахождение максимальной длины для каждого столбца
    int max_lengths[MAX_COLS] = {0};
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < MAX_COLS; j++) {
            int length = strlen(data[i][j]);
            if (length > max_lengths[j]) {
                max_lengths[j] = length;
            }
        }
    }

    // Вывод данных с выровненными столбцами
    // Вывод данных с выровненными столбцами и заголовками
printf("%-*s  %-*s    %-*s\n", max_lengths[0], "Предприятие", max_lengths[1], "Кол-во заказов", max_lengths[2] + 10, "Чистый доход, млн.р.");
for (int i = 0; i < rows; i++) {
    printf("%-*s      %-*s                    %-*s\n", max_lengths[0], data[i][0], max_lengths[1], data[i][1], max_lengths[2] + 10, data[i][2]);
}

    printf("\n\n\n\n\n\n");

    // Вычисление статистики для массива количеств заказов
    float Sx, Srx, Somx;
    statistic(rows, orders, income, &Sx, &Srx, &Somx);

    // Вычисление статистики для массива суммы дохода
    float Sy, Sry, Somy;
    statistic(rows, income, orders, &Sy, &Sry, &Somy);

    // Вывод результатов статистики для массива количеств заказов
    printf("Статистики вычисленные в массиве заказов\n");
    printf("Среднее значение: %-15.2f\n", Srx);
    printf("Среднеквадратическое отклонение: %.3f\n\n", Somx);

    // Вывод результатов статистики для массива суммы дохода
    printf("Статистики вычисленные в массиве суммы дохода\n");
    printf("Среднее значение: %-15.2f\n", Sry);
    printf("Среднеквадратическое отклонение: %.3f\n\n", Somy);

    // Вычисление коэффициента корреляции
    float r = top(rows, orders, Srx, income, Sry) / ((rows - 1) * Somx * Somy);

    // Вывод коэффициента корреляции
    printf("Коэффициент корреляции: %.3f\n\n", r);

    // Если коэффициент корреляции меньше или равен 0.5, меняем цвет вывода и выводим сообщение
    if (fabs(r) <= 0.5) {
        system("color FC"); // Изменение цвета текста в консоли (F - ярко-красный, C - ярко-синий)
        printf("Связь между x и y слабая!\n"); // Вывод сообщения о слабой связи между x и y
    } else {
    	printf("Связь между x и y сильная!\n");
float a0, a1; // Коэффициенты регрессии
float regr1[MAX_ROWS], regr2[MAX_ROWS]; // Массивы для значений регрессии

// Первая регрессия
regr(rows, Sy, fi1, orders, &a0, &a1, income); // Вычисление коэффициентов a0 и a1 для первой регрессии
setcolor(GREEN);
int prevX1 = 0, prevY1 = 0; // Переменные для хранения предыдущей точки первой регрессии
for (int i = 0; i < rows; i++) {
    regr1[i] = a0 + a1 * fi1(orders[i]); // Вычисление значений первой регрессии
    int x1 = leftMargin + (int)((orders[i] / MAX_ROWS) * xAxisLength);
    int y1 = topMargin + yAxisLength - (int)((regr1[i] / maxIncome) * yAxisLength);
    if (i > 0) {
        line(prevX1, prevY1, x1, y1); // Соединение текущей и предыдущей точек первой регрессии
    }
    prevX1 = x1;
    prevY1 = y1;
}
//введение 
// Постановка задачи(ссылка на приложение с файлом)
//Подготовка тестов(график с excel+ данные)
//
// Вторая регрессия
regr(rows, Sy, fi2, orders, &a0, &a1, income); // Вычисление коэффициентов a0 и a1 для второй регрессии
setcolor(RED);
int prevX2 = 0, prevY2 = 0; // Переменные для хранения предыдущей точки второй регрессии
for (int i = 0; i < rows; i++) {
    regr2[i] = a0 + a1 * fi2(orders[i]); // Вычисление значений второй регрессии
    int x2 = leftMargin + (int)((orders[i] / MAX_ROWS) * xAxisLength);
    int y2 = topMargin + yAxisLength - (int)((regr2[i] / maxIncome) * yAxisLength);
    if (i > 0) {
        line(prevX2, prevY2, x2, y2); // Соединение текущей и предыдущей точек второй регрессии
    }
    prevX2 = x2;
    prevY2 = y2;
}

        
        float mean_income = average(rows, income); // вычисление среднего значения дохода

    float variance = disp(rows, mean_income, income); // вычисление дисперсии по переменной дохода
printf("Регрессия 1\t\tРегрессия 2\n");
for (int i = 0; i < rows; i++) {
    printf("%.3f\t\t\t%.3f\n", regr1[i], regr2[i]);
}
 printf("\n\n");
printf("Коэффициенты а0 и а1 для первой регрессии:\n a0=%.3f\n a1=%.3f\n\n", a0, a1);
printf("Коэффициенты а0 и а1 для второй регрессии:\n a0=%.3f\n a1=%.3f\n\n", a0, a1);
    printf("Дисперсия по y: %lf\n", variance);
    

        
        
        float sum_of_squared_diff = 0;
    	for (int i = 0; i < rows; i++) {
        float diff = income[i] - regr1[i];
        float squared_diff = diff * diff;
        sum_of_squared_diff += squared_diff;
    }
    float mean_squared_diff = sum_of_squared_diff / rows;

    // Выводим среднее значение квадратов разностей
    printf("Остаточная дисперсия первой регрессии:%f\n", mean_squared_diff);
    
    
    float sum_of_squared_diff1 = 0;
    	for (int i = 0; i < rows; i++) {
        float diff1 = income[i] - regr2[i];
        float squared_diff1 = diff1 * diff1;
        sum_of_squared_diff1 += squared_diff1;
    }
    
    
    float mean_squared_diff1 = sum_of_squared_diff1 / rows;

    // Выводим среднее значение квадратов разностей
    printf("Остаточная дисперсия второй регрессии:%f\n", mean_squared_diff1);
        
        
        float fisher = variance / mean_squared_diff;

    // Выводим коэффициент Фишера
    printf("Коэффициент Фишера для первой регрессии: %.2f\n", fisher);
                float fisher1 = variance / mean_squared_diff1;

    // Выводим коэффициент Фишера
    printf("Коэффициент Фишера для второй регрессии: %.2f\n", fisher1);
    
        if (fisher > fisher1)
    puts("Первая регрессия лучше описывает зависимость.");
else
    puts("Вторая регрессия лучше описывает зависимость.");

        
        
    }


getch();
closegraph();
    return 0;
}
  • Вопрос задан
  • 62 просмотра
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Читайте построчно до конца файла. У вас уже эта проверка есть там, где вы fscanf делаете - вы же проверяете, что оно вернуло? А столбцов у вас всегда 3.

Если проблема с тем, что у вас массив, куда вы читаете, ограниченного размера, то можно, например, завести его достаточно большой длины, с запасом. Как у вас там 101 символ выделен под кажую строку. А еще лучше, если у вас C++, использовать std::vector - ему можно длину динамически менять. Если же это C - то пишите свою собственную логику увеличения массива, через malloc и realloc по мере заполнения.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы