Моя цель - сгенерировать случайные числа в новый текстовый файл, где я могу получить случайно сгенерированные значения и подсчитать количество вхождений значений (например, число 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 Извините за это. Я просто хотел знать, почему мой код не работает должным образом.
@Tee, каким образом «работает не так, как предполагалось»?
@ 4386427 Я получаю вывод «среднее значение = 0,0000», когда я должен получить вывод «Число 1 появлялось «x» раз» и «среднее значение = 3,412» и т. д.
@Tee Вы открыли txt-файл в редакторе, чтобы убедиться, что файл выглядит нормально?
@ 4386427 Да, мой текстовый файл вышел, как и предполагалось.
@Tee Вы пытались распечатать значения внутри цикла, который читает текстовый файл? Нравится printf("%d\n", value);
@ 4386427 Да, мой текстовый файл вывел 600 значений из строки 1 - 600, но моя программа не читала и не записывала значения должным образом.
@Tee Вы пытались подсчитать, сколько значений вы прочитали из файла? Сделайте это и используйте здесь: mean = sum / 600
--> mean = sum / COUNT
@Tee Опубликуйте первые 10 строк текстового файла (используйте ссылку «редактировать» и добавьте ее к вопросу)
@ 4386427 тогда попробую :D
пожалуйста, добавьте фактическую ошибку, которую вы получаете, к вопросу
относительно: char fname[20]; .... scanf("%19s",fname); strcat(fname, ".txt");
если вы введете имя файла из 15 или более символов, то вызов strcat()
переполнит буфер fname[]
, что приведет к неопределенному поведению
OT: относительно: fp=fopen(fname, "w");
всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция прошла успешно. Если не удалось (==NULL), вызовите perror( "fopen failed" );
, а затем: exit( EXIT_FAILURE );
OT: относительно: while (result == 1) { { num[value] = num[value] + 1; // num[value]++ } result = fscanf(fpointer, "%d", &value); }
Зачем лишние фигурные скобки '{' и '}' ?
почему один и тот же файл открывается в main()
и открывается в `newfile()?
относительно: int newfile(FILE *fp)
и int i, N = 600, newfile[N];
использование одного и того же имени для функции и для переменной внутри этой функции является очень плохой практикой программирования и (особенно со старыми компиляторами) приводит к рекурсивному вызову.
OT: в опубликованном коде есть какие-то "магические" числа. «магические» числа — это числа без основы. «магические» числа значительно усложняют понимание кода, отладку и т. д. Эти «магические» числа: 6, 20, 600. Предложите использовать операторы #define
или оператор enum
, чтобы дать этим «магическим» числам осмысленные имена. Затем, используя эти значимые имена по всему коду
относительно: int newfile(FILE *fp)
и fp=fopen(fname, "w");
Это изменит указатель в списке параметров, но не изменит file*
обратно в функцию main()
.
ОТ: относительно; do { newfile(fp); i++; } while (i<1);
почему петля? все что нужно это: newfile( fp );
OT: относительно: printf("ERROR: CANNOT OPEN FILE!\n");
Сообщения об ошибках должны выводиться на stderr
, а не на stdout
. Если сбойная функция является библиотечной функцией C, то Then также должен вывести текст причины, по которой система считает, что произошла ошибка. Утверждение: perror( "fopen failed" );
справляется со всем этим.
относительно: sum = (1*(num[1])+2*(num[2])+3*(num[3])+4*(num[4])+5*(num[5])+6*(num[6]));
1) используется только 6 элементов массива num[]
, поэтому размер массива можно уменьшить до 6. 2) в C индексы массива находятся в диапазоне от 0 ... (количество элементов в массиве -1)
относительно: в main(): scanf("%19s",filename); fpointer = fopen(filename, "r");
и в newfile(): scanf("%15s",fname); strcat(fname, ".txt"); fp=fopen(fname, "w");
это означает, что пользователь должен ввести два (несколько) разных имени файла, одно с расширением и одно без расширения. Это будет очень запутанно для пользователя.
OT: вместо того, чтобы дважды получать имя файла, предложите получить один раз в начале main()
и передать полученный массив символов в newfile()
. Не забудьте вызвать fclose()
в newfile()
, чтобы «новый» файл был полностью готов к повторному открытию и чтению в функции main()
.
OT: предлагаю: вместо того, чтобы открывать/закрывать/открывать/закрывать файл, откройте его только один раз в начале main()
с режимом «w+» и перед возвратом из newfile()
для вызова rewind();
Основная проблема в вашем коде в том, что вы забыли закрыть файл внутри функции newfile
.
Так что просто добавьте fclose(fp);
в конце функции.
Незначительные проблемы:
вам не нужно передавать fp
в функцию newfile
. Просто используйте локальную переменную.
newfile[N]
совсем не нужен. Просто сделайте: fprintf(fp,"%d\n", (rand() % 6)+1);
num[600] = { 0 };
слишком велик, так как вы используете только индекс 0 .. 6
Прежде чем делать num[value] = ...
, вы должны убедиться, что value
находится в ожидаемом диапазоне, т. е. чтобы избежать записи за границы.
Тут нет вопросов!!!