我试图从输入的数据集中找到用户选择的列的平均值、标准差、偏度和众数。平均值、标准差和偏度都可以正常工作并打印,但众数却不行。
每个函数的设置方式完全相同,但数学不同。 mode 函数应该找到用户选择的列的模式并返回最大值(模式)。然后在 main 中调用该函数并打印一条 printf 语句,该语句打印类似“第 1 列的众数是:1”
我包含了偏度函数,因此您可以看到这些函数遵循相同的格式,但偏度有效,而模式则不然。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
double** load_data(FILE* file, int numrows, int numcols);
char** load_header(FILE* file, int numcols);
int num_rows_in_file(FILE* file);
int num_cols_in_file(FILE* file);
int mode(double** dataset, int numrows, int col);
int main(void) {
FILE* ecg_File;
fopen_s(&ecg_File, "cardio_dataset.dat", "r");
// The number of rows/cols in the ECG data.
int num_ecg_rows = num_rows_in_file(ecg_File);
int num_ecg_cols = num_cols_in_file(ecg_File);
printf("number of rows = %d number of columns = %d\n", num_ecg_rows, num_ecg_cols);
// Load our ECG dataset in to what we'll treat as 2d arrays- So we can index it as ergo_data[rowind][colind]
char** ecg_header = load_header(ecg_File, num_ecg_cols);
double** ecg_data = load_data(ecg_File, num_ecg_rows, num_ecg_cols);
// User input
int user_row, user_col;
getUserInput(&user_row, &user_col, num_ecg_rows, num_ecg_cols);
//printf("row = %d column = %d\n", user_row, user_col);
int mode_val = mode(ecg_data, num_ecg_rows, user_col);
printf("Mode of column %d: %lf/n ", user_col, mode_val);
fclose(ecg_File);
return 0;
}
//User input
void getUserInput(int *row, int *col, int numrows, int numcols) {
do {
printf("Enter row you'd like to observe(0-%d): ", numrows - 1);
scanf("%d", row);
printf("Enter column you'd like to observe(0-%d): ", numcols - 1);
scanf("%d", col);
} while (*row < 0 || *row >= numrows || *col < 0 || *col >= numcols);
}
//Mode
int mode(double** dataset, int numrows, int col){
int maxValue = 0;
int maxCount = 0;
for (int i = 0; i < numrows-1; ++i) {
int count = 0;
for (int j = 0; j < numrows-1; ++j) {
if (dataset[j][col] == dataset[i][col])
++count;
}
if (count > maxCount) {
maxCount = count;
maxValue += dataset[i][col];
}
}
return maxValue;
}
char** load_header(FILE* file, int numcols) {
char** dataset = (char**)calloc(numcols, sizeof(char*)); // Allocate a block of memory for each of our column headers.
char buf[512]; // Make a buffer we'll use to grab a whole row. Make it big.
if (fgets(buf, 512, file) != NULL) {
dataset[0] = strtok(buf, "\n\r\t,");
printf("Header 0: %s\n", dataset[0]);
int i = 1;
while (dataset[i-1] != NULL) {
dataset[i] = strtok(NULL, " \n\r\t,");
if ((dataset[i] != NULL)) {
printf("Header %d: %s\n", i, dataset[i]);
}
i++;
}
}
return dataset;
}
double** load_data(FILE* file, int numrows, int numcols) {
if (file != NULL) {
double** dataset = (double**)calloc(numrows, sizeof(double*)); // Allocate each of our row pointers.
if (dataset == NULL) {
return NULL; }
for (int i = 0; i < numrows-1; i++) {
dataset[i] = (double*)calloc(numcols, sizeof(double)); // Allocate our columns.
if (dataset[i] == NULL) {
return NULL;
}
}
for (int i = 0; i < numrows-1; i++) {
for (int j = 0; j < numcols; j++) {
fscanf(file, "%lf,", &dataset[i][j]); //read content of file per element
}
}
return dataset;
}
else {
fprintf_s(stderr, "Unable to find file! Ensure it is in the Debug directory.");
return NULL;
}
}
int num_cols_in_file(FILE* file) {
int numcols = 0;
if (file) {
char buf[100]; // Make a buffer we'll use to grab a whole row.
if (fgets(buf, 100, file) != NULL) {
// Tokenize our buffer, looking for how many columns we have (aka how many tokens we can create)
char* token;
char* next_token = NULL;
token = strtok_s(buf, " \n\r\t,", &next_token);
while (token != NULL) {
token = strtok_s(NULL, " \n\r\t,", &next_token);
numcols++;
}
rewind(file); // Reset our position to the beginning of the file.
return numcols;
}
else {
fprintf_s(stderr, "Failed to read first row.");
return 0;
}
rewind(file); // Reset our position to the beginning of the file.
}
else {
fprintf_s(stderr, "File is unopened. Numcols only works on opened files.");
}
}
int num_rows_in_file(FILE* file) {
int numrows = 0;
if (file) {
char buf[100]; // Make a buffer we'll use to grab a whole row.
while (fgets(buf, 100, file) != NULL) {
numrows++;
}
rewind(file); // Reset our position to the beginning of the file.
return numrows;
}
else {
fprintf_s(stderr, "File is unopened. Numrows only works on opened files.");
return 0;
}
}
我的模式功能不会在 main 中打印,而其他所有功能都会打印?
在不深入研究代码的情况下,我建议OP重新编译代码并打开许多警告。
下面是一些示例问题。删除帖子,尝试解决以下问题,然后重新发帖。
warning: implicit declaration of function 'getUserInput' [-Wimplicit-function-declaration]
32 | getUserInput(&user_row, &user_col, num_ecg_rows, num_ecg_cols);
| ^~~~~~~~~~~~
warning: format '%lf' expects argument of type 'double', but argument 3 has type 'int' [-Wformat=]
36 | printf("Mode of column %d: %lf/n ", user_col, mode_val);
| ~~^ ~~~~~~~~
| | |
| double int
| %d
warning: unused variable 'ecg_header' [-Wunused-variable]
27 | char **ecg_header = load_header(ecg_File, num_ecg_cols);
| ^~~~~~~~~~
43:6: warning: conflicting types for 'getUserInput'; have 'void(int *, int *, int, int)'
43 | void getUserInput(int *row, int *col, int numrows, int numcols) {
| ^~~~~~~~~~~~
32:3: note: previous implicit declaration of 'getUserInput' with type 'void(int *, int *, int, int)'
32 | getUserInput(&user_row, &user_col, num_ecg_rows, num_ecg_cols);
| ^~~~~~~~~~~~
In function 'mode':
70:19: warning: conversion from 'double' to 'int' may change value [-Wfloat-conversion]
70 | maxValue += dataset[i][col];
| ^~~~~~~
In function 'load_header':
78:36: warning: conversion to 'size_t' {aka 'long unsigned int'} from 'int' may change the sign of the result [-Wsign-conversion]
78 | char **dataset = (char**) calloc(numcols, sizeof(char*)); // Allocate a block of memory for each of our column headers.
| ^~~~~~~
In function 'load_data':
100:42: warning: conversion to 'size_t' {aka 'long unsigned int'} from 'int' may change the sign of the result [-Wsign-conversion]
100 | double **dataset = (double**) calloc(numrows, sizeof(double*)); // Allocate each of our row pointers.
| ^~~~~~~
107:37: warning: conversion to 'size_t' {aka 'long unsigned int'} from 'int' may change the sign of the result [-Wsign-conversion]
107 | dataset[i] = (double*) calloc(numcols, sizeof(double)); // Allocate our columns.
| ^~~~~~~
In function 'num_cols_in_file':
138:15: warning: implicit declaration of function 'strtok_s'; did you mean 'strtok'? [-Wimplicit-function-declaration]
138 | token = strtok_s(buf, " \n\r\t,", &next_token);
| ^~~~~~~~
| strtok
138:13: warning: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
138 | token = strtok_s(buf, " \n\r\t,", &next_token);
| ^
141:15: warning: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
141 | token = strtok_s(NULL, " \n\r\t,", &next_token);
| ^
In function 'num_cols_in_file':
156:1: warning: control reaches end of non-void function [-Wreturn-type]
156 | }
| ^