Программирование на C — генерация случайных чисел в новый текстовый файл и извлечение их для подсчета вхождений (затем сделайте статистику сбоку)

Моя цель - сгенерировать случайные числа в новый текстовый файл, где я могу получить случайно сгенерированные значения и подсчитать количество вхождений значений (например, число 1 появлялось "x" количество раз). Мой ожидаемый вывод должен отображать вывод, подобный приведенному в примере, и все вхождения должны составлять до 600. В моей функции newfile() в последней скобке есть подчеркивание. Заранее спасибо.

Первые 10 строк выходного файла txt...

2

5

4

2

6

2

5

1

4

2

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

int newfile(FILE *fp)
{
  char fname[20];
  printf("\nEnter the name of the file...  ");
  scanf("%19s",fname);//File name cannot have spaces
  strcat(fname, ".txt");
  fp=fopen(fname, "w");
  int i, N = 600, newfile[N];
  for(i=0;i<N;i++)
  {
     newfile[i]= ((rand() % 6)+1);
     fprintf(fp,"%d\n",newfile[i]);
  }
}

int main() 
{
  int i = 0;
  FILE *fp;
  do
  {
    newfile(fp);
    i++;
  }
  while (i<1);
    FILE* fpointer;
    char filename[20];
    int value = 0, result = 0, num[600] = { 0 };
    float sum, mean;

    printf("\nEnter the name of the file...  ");
    scanf("%19s",filename);
    fpointer = fopen(filename, "r");

    if (fpointer == NULL) {
        printf("ERROR: CANNOT OPEN FILE!\n");
        return -1;
    }

    result = fscanf(fpointer, "%d", &value);
    while (result == 1)
    {
        {
            num[value] = num[value] + 1;  // num[value]++
        }
        result = fscanf(fpointer, "%d", &value);
    }

    for (int i = 0; i <= 6; i++) {
        if (num[i] > 0) {
            printf("Number %i has appeared %d times\n", i, num[i]);
        }
    }
    
    sum = (1*(num[1])+2*(num[2])+3*(num[3])+4*(num[4])+5*(num[5])+6*(num[6]));

    mean = sum / 600;
    printf("\nThe mean is %f",mean);


    fclose(fpointer);
    return 0;
}

Тут нет вопросов!!!

goodvibration 14.12.2020 12:00

@goodvibration Извините за это. Я просто хотел знать, почему мой код не работает должным образом.

Tee 14.12.2020 12:02

@Tee, каким образом «работает не так, как предполагалось»?

Support Ukraine 14.12.2020 12:03

@ 4386427 Я получаю вывод «среднее значение = 0,0000», когда я должен получить вывод «Число 1 появлялось «x» раз» и «среднее значение = 3,412» и т. д.

Tee 14.12.2020 12:06

@Tee Вы открыли txt-файл в редакторе, чтобы убедиться, что файл выглядит нормально?

Support Ukraine 14.12.2020 12:08

@ 4386427 Да, мой текстовый файл вышел, как и предполагалось.

Tee 14.12.2020 12:09

@Tee Вы пытались распечатать значения внутри цикла, который читает текстовый файл? Нравится printf("%d\n", value);

Support Ukraine 14.12.2020 12:10

@ 4386427 Да, мой текстовый файл вывел 600 значений из строки 1 - 600, но моя программа не читала и не записывала значения должным образом.

Tee 14.12.2020 12:13

@Tee Вы пытались подсчитать, сколько значений вы прочитали из файла? Сделайте это и используйте здесь: mean = sum / 600 --> mean = sum / COUNT

Support Ukraine 14.12.2020 12:14

@Tee Опубликуйте первые 10 строк текстового файла (используйте ссылку «редактировать» и добавьте ее к вопросу)

Support Ukraine 14.12.2020 12:15

@ 4386427 тогда попробую :D

Tee 14.12.2020 12:16

пожалуйста, добавьте фактическую ошибку, которую вы получаете, к вопросу

Slipoch 15.12.2020 01:23

относительно: char fname[20]; .... scanf("%19s",fname); strcat(fname, ".txt"); если вы введете имя файла из 15 или более символов, то вызов strcat() переполнит буфер fname[], что приведет к неопределенному поведению

user3629249 15.12.2020 18:33

OT: относительно: fp=fopen(fname, "w"); всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция прошла успешно. Если не удалось (==NULL), вызовите perror( "fopen failed" );, а затем: exit( EXIT_FAILURE );

user3629249 15.12.2020 18:38

OT: относительно: while (result == 1) { { num[value] = num[value] + 1; // num[value]++ } result = fscanf(fpointer, "%d", &value); } Зачем лишние фигурные скобки '{' и '}' ?

user3629249 15.12.2020 18:43

почему один и тот же файл открывается в main() и открывается в `newfile()?

user3629249 15.12.2020 18:46

относительно: int newfile(FILE *fp) и int i, N = 600, newfile[N]; использование одного и того же имени для функции и для переменной внутри этой функции является очень плохой практикой программирования и (особенно со старыми компиляторами) приводит к рекурсивному вызову.

user3629249 15.12.2020 18:49

OT: в опубликованном коде есть какие-то "магические" числа. «магические» числа — это числа без основы. «магические» числа значительно усложняют понимание кода, отладку и т. д. Эти «магические» числа: 6, 20, 600. Предложите использовать операторы #define или оператор enum, чтобы дать этим «магическим» числам осмысленные имена. Затем, используя эти значимые имена по всему коду

user3629249 15.12.2020 18:53

относительно: int newfile(FILE *fp) и fp=fopen(fname, "w"); Это изменит указатель в списке параметров, но не изменит file* обратно в функцию main().

user3629249 15.12.2020 18:57

ОТ: относительно; do { newfile(fp); i++; } while (i<1); почему петля? все что нужно это: newfile( fp );

user3629249 15.12.2020 19:00

OT: относительно: printf("ERROR: CANNOT OPEN FILE!\n"); Сообщения об ошибках должны выводиться на stderr, а не на stdout. Если сбойная функция является библиотечной функцией C, то Then также должен вывести текст причины, по которой система считает, что произошла ошибка. Утверждение: perror( "fopen failed" ); справляется со всем этим.

user3629249 15.12.2020 19:03

относительно: sum = (1*(num[1])+2*(num[2])+3*(num[3])+4*(num[4])+5*(num[5])+6*(n‌​um[6])); 1) используется только 6 элементов массива num[], поэтому размер массива можно уменьшить до 6. 2) в C индексы массива находятся в диапазоне от 0 ... (количество элементов в массиве -1)

user3629249 15.12.2020 19:08

относительно: в main(): scanf("%19s",filename); fpointer = fopen(filename, "r"); и в newfile(): scanf("%15s",fname); strcat(fname, ".txt"); fp=fopen(fname, "w"); это означает, что пользователь должен ввести два (несколько) разных имени файла, одно с расширением и одно без расширения. Это будет очень запутанно для пользователя.

user3629249 15.12.2020 19:15

OT: вместо того, чтобы дважды получать имя файла, предложите получить один раз в начале main() и передать полученный массив символов в newfile(). Не забудьте вызвать fclose() в newfile(), чтобы «новый» файл был полностью готов к повторному открытию и чтению в функции main().

user3629249 15.12.2020 19:17

OT: предлагаю: вместо того, чтобы открывать/закрывать/открывать/закрывать файл, откройте его только один раз в начале main() с режимом «w+» и перед возвратом из newfile() для вызова rewind();

user3629249 15.12.2020 19:23
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
25
164
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Так что просто добавьте fclose(fp); в конце функции.

Незначительные проблемы:

вам не нужно передавать fp в функцию newfile. Просто используйте локальную переменную.

newfile[N] совсем не нужен. Просто сделайте: fprintf(fp,"%d\n", (rand() % 6)+1);

num[600] = { 0 }; слишком велик, так как вы используете только индекс 0 .. 6

Прежде чем делать num[value] = ..., вы должны убедиться, что value находится в ожидаемом диапазоне, т. е. чтобы избежать записи за границы.

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