我有一个混合类型的数组(整数和双精度数)。 我需要通读输入值的行。
我试图将第 2~11 行的前两个值存储为数组,并将同一行的第 4~13 个值存储为 10*10 数组
我想将它们传递给 C 编译器并使用 printf 函数打印出这些值。但是,当我尝试存储双精度数以查找 (73.29 77.35 66.66 44.12 49.65 60.72 78.76 29.45 15.16 的平均值时,我在存储值时遇到了问题,并收到错误“不兼容的指针到整数转换返回'int [10][2]'” 35.70)在第二个ROM中
这些是输入值。
10
104 80 34.31 73.29 77.35 66.66 44.12 49.65 60.72 78.76 29.45 15.16 35.70 106 121 114
106 90 49.36 49.33 47.02 40.86 46.57 49.04 49.77 40.75 49.54 42.33 43.42 124 -1
114 90 80.85 81.50 66.26 84.71 50.63 17.01 70.02 54.95 82.38 28.54 69.71 132 -1
121 60 33.65 10.47 51.25 57.63 13.60 44.24 17.20 33.32 24.15 29.60 24.25 201 -1
124 40 31.13 36.52 24.10 29.71 28.05 16.02 32.55 15.17 36.31 30.95 20.39 221 351 -1
132 60 29.42 15.55 30.03 29.92 22.67 21.25 11.80 23.48 25.30 23.52 22.90 121 797 -1
201 80 43.27 06.62 10.43 12.28 21.59 32.42 22.72 22.11 27.61 21.36 27.77 -1
221 50 24.16 48.13 44.73 43.19 49.57 47.68 39.90 49.93 45.13 45.58 41.50 -1
351 90 77.83 86.72 82.94 85.29 85.66 85.58 81.95 84.71 88.00 89.49 84.69 104 797 -1
797 40 22.11 20.26 26.67 24.44 27.17 27.29 22.07 24.14 20.30 10.67 24.16 -1
0.6 0.8
int main(int argc, char* argv[]){
int rows;
int location_ID, speed_lim;
double latest_ave_speed;
double historical_speed[10];
double location_details[10][2];
//for scanning the traffic data
int val;
double speed;// each of the speed values recorded
//fiugre out the number of rows of locations
scanf("%d" ,&rows);
//reading each line
//the first three vals
while (scanf("%d %d %lf", &location_ID, &speed_lim, &latest_ave_speed )== 3){
//get the location details
for (int i=0; i<10; i++){
for(int j=0; j<2; j++){
location_details[i][j]= scanf("%d",&val);
}
return location_details;
for(int j=3; j<12; j++){
historical_speed[j-3] =scanf("%lf", &speed);
merged_historical_speed(historical_speed);
}
我试图将数据重新排列成一个 10X2 整数数组来存储第 2~11 行的前两个整数,以及一个 10X10 数组来存储这些行的第 3~12 列以返回双精度数的平均值。
请贴出完整的程序。
您不会将数据传递到
C
编译器。您将把您的数据传递给这个 C
程序。
当然,我们可以说您有一个混合类型的数组,但似乎您有一组具有预定义格式的数据读数,例如
而且您似乎想获得读数的平均值。
如果有数十个字段,简单的方法是编写一个简单的函数解析器,其中包含一个构建每个记录的循环和一个获取每个字段的内部循环。
由于只有 13 个字段,我们可以使用简单的
scanf
或 sscanf
调用。
我将在这里展示一个小例子。在示例中,我不会显示所有字段,只是因为它很无聊。
但我会向您展示一种安全的方法来编写此类内容。
围绕数据编写:代码离数据越远,完成它的难度就越大。您的数据记录似乎是
typedef struct
{
int location;
int limit;
double latest_average;
double reading[10];
double avg;
} Speed_data;
由于似乎需要平均值,因此可以在读取数据时计算平均值,然后将其保存在结构体中。或不。我救了。
还有一堆记录,比如
typedef struct
{
unsigned size;
Speed_data* rcd;
} Data_set;
始终对数据进行封装。 OOP 有其价值...
并且有一个如上所述的输入文件...一个好的开始是考虑这样的程序
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char* in_file = "data.txt";
FILE* in = fopen(in_file, "r");
if (in == NULL) return -1;
fprintf(stderr, " '%s' open\n", in_file);
char line[250] = {0};
char* p = line; // p points to line
p = fgets(line, sizeof(line), in);
if (p == NULL) return -2; // read nothing
const int N = atoi(line);
if (N < 1) return -3;
fprintf(stderr, " Reading %d lines of data\n", N);
for (int i = 0; i < N; i += 1)
{
p = fgets(line, sizeof(line), in);
if (p == NULL)
{
fprintf(
stderr,
" Error after after reading %d lines\n",
i);
break;
}
fprintf(stderr, "%4d %s", i, line);
}
fclose(in);
return 0;
}
总的来说,首先,确保数据按预期读取、文件被消耗等等......
'data.txt' open
Reading 10 lines of data
0 104 80 34.31 73.29 77.35 66.66 44.12 49.65 60.72 78.76 29.45 15.16 35.70 106 121 114
1 106 90 49.36 49.33 47.02 40.86 46.57 49.04 49.77 40.75 49.54 42.33 43.42 124 -1
2 114 90 80.85 81.50 66.26 84.71 50.63 17.01 70.02 54.95 82.38 28.54 69.71 132 -1
3 121 60 33.65 10.47 51.25 57.63 13.60 44.24 17.20 33.32 24.15 29.60 24.25 201 -1
4 124 40 31.13 36.52 24.10 29.71 28.05 16.02 32.55 15.17 36.31 30.95 20.39 221 351 -1
5 132 60 29.42 15.55 30.03 29.92 22.67 21.25 11.80 23.48 25.30 23.52 22.90 121 797 -1
6 201 80 43.27 06.62 10.43 12.28 21.59 32.42 22.72 22.11 27.61 21.36 27.77 -1
7 221 50 24.16 48.13 44.73 43.19 49.57 47.68 39.90 49.93 45.13 45.58 41.50 -1
8 351 90 77.83 86.72 82.94 85.29 85.66 85.58 81.95 84.71 88.00 89.49 84.69 104 797 -1
9 797 40 22.11 20.26 26.67 24.44 27.17 27.29 22.07 24.14 20.30 10.67 24.16 -1
这有利于道德支持;)
Data_set
来保存它考虑这个示例程序和类似的函数
Speed_data* so_cnvrt(const char* ln);
这可以将一条线转换为具有正确字段和计算平均值的
struct
Speed_data
。
也考虑一个函数
int so_show(Data_set* set, const char* msg)
可以在文件中打印完整的数据集
所以这个
main.c
可以工作:
int main(void)
{
// open file
const char* in_file = "data.txt";
FILE* in = fopen(in_file, "r");
if (in == NULL) return -1;
fprintf(stderr, " '%s' open\n", in_file);
char line[250] = {0};
char* p = line; // p points to line
// get size of input
p = fgets(line, sizeof(line), in);
if (p == NULL) return -2; // read nothing
const int N = atoi(line);
if (N < 1) return -3;
// create array
Data_set data = {0};
data.size = 10;
data.rcd = malloc(data.size * sizeof(Speed_data));
if (data.rcd == NULL) return -4;
// process input
fprintf(stderr, " Reading %d lines of data\n ", N);
for (int i = 0; i < N; i += 1)
{
p = fgets(line, sizeof(line), in);
if (p == NULL) break;
Speed_data* one = so_cnvrt(line);
if (NULL == one) // read error
{
fprintf(
stderr, " Error after %d lines\n", i);
free(data.rcd);
free(one);
fclose(in);
break;
}
data.rcd[i] = *one; // shallow copy
}
fclose(in);
so_show(&data, "a simple test");
free(data.rcd); // free data
return 0;
}
这是从第一个程序复制和粘贴的问题。有用吗?
'data.txt' open
Reading 10 lines of data
a simple test 10 lines in this set:
-------------------------------------------------
| | | average |
| loc | lim | latest | actual |
-------------------------------------------------
| 104 | 80 | 34.31 | 53.09 |
| 106 | 90 | 49.36 | 45.86 |
| 114 | 90 | 80.85 | 60.57 |
| 121 | 60 | 33.65 | 30.57 |
| 124 | 40 | 31.13 | 26.98 |
| 132 | 60 | 29.42 | 22.64 |
| 201 | 80 | 43.27 | 20.49 |
| 221 | 50 | 24.16 | 45.53 |
| 351 | 90 | 77.83 | 85.50 |
| 797 | 40 | 22.11 | 22.72 |
-------------------------------------------------
它有效。我没有打印这 10 篇阅读材料,只是因为它很无聊。但这是编辑功能的问题。
C
代码#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int location;
int limit;
double latest_average;
double reading[10];
double avg;
} Speed_data;
Speed_data* so_cnvrt(const char*); // 1 line => 1 record
typedef struct
{
unsigned size;
Speed_data* rcd;
} Data_set;
int so_show(Data_set*,const char*);
int main(void)
{
// open file
const char* in_file = "data.txt";
FILE* in = fopen(in_file, "r");
if (in == NULL) return -1;
fprintf(stderr, " '%s' open\n", in_file);
char line[250] = {0};
char* p = line; // p points to line
// get size of input
p = fgets(line, sizeof(line), in);
if (p == NULL) return -2; // read nothing
const int N = atoi(line);
if (N < 1) return -3;
// create array
Data_set data = {0};
data.size = 10;
data.rcd = malloc(data.size * sizeof(Speed_data));
if (data.rcd == NULL) return -4;
// process input
fprintf(stderr, " Reading %d lines of data\n ", N);
for (int i = 0; i < N; i += 1)
{
p = fgets(line, sizeof(line), in);
if (p == NULL) break;
Speed_data* one = so_cnvrt(line);
if (NULL == one) // read error
{
fprintf(
stderr, " Error after %d lines\n", i);
free(data.rcd);
free(one);
fclose(in);
break;
}
data.rcd[i] = *one; // shallow copy
}
fclose(in);
so_show(&data, "a simple test");
free(data.rcd); // free data
return 0;
}
Speed_data* so_cnvrt(const char* ln)
{
if (ln == NULL) return NULL; // no data
const char* mask =
"\
%d %d %lf\
%lf %lf %lf %lf %lf\
%lf %lf %lf %lf %lf";
Speed_data* one = malloc(sizeof(Speed_data));
if (one == NULL) return NULL;
int res = sscanf(
ln, mask, &one->location, &one->limit,
&one->latest_average, &one->reading[0],
&one->reading[1], &one->reading[2], &one->reading[3],
&one->reading[4], &one->reading[5], &one->reading[6],
&one->reading[7], &one->reading[8], &one->reading[9]);
if (res != 13)
{
free(one);
return NULL;
};
one->avg = 0.;
for (int i = 0; i < 10; i += 1)
one->avg += one->reading[i];
one->avg /= 10;
return one;
}
int so_show(Data_set* set, const char* msg)
{
if (set == NULL) return -1;
if (msg != NULL) printf("%s", msg);
printf(" %d lines in this set:\n\n", set->size);
const char* l0 =
"-------------------------------------------------";
const char* l1 =
"| | | average |";
const char* l2 =
"| loc | lim | latest | actual |";
printf("%s\n%s\n%s\n%s\n", l0,l1,l2,l0);
for (unsigned i = 0; i < set->size; i += 1)
{
printf(
"| %3d | %3d | %6.2f | %6.2f "
"|\n",
set->rcd[i].location, set->rcd[i].limit,
set->rcd[i].latest_average, set->rcd[i].avg);
}
printf("%s\n\n",l0);
return 0;
}
这不是一个完整的解决方案,但可能是一种方法。