我是一个非常基本的用户,对C中使用的命令知之甚少,所以请耐心等待...我不能使用非常复杂的代码。我对stdio.h和ctype.h库有一些了解,但就此而言。 我在txt文件中有一个矩阵,我想根据输入的行数和列数来加载矩阵
例如,我在文件中有一个5乘5的矩阵。我想提取一个特定的2乘2子矩阵,我该怎么做?
我使用:
创建了一个嵌套循环FILE *sample
sample=fopen("randomfile.txt","r");
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
fscanf(sample,"%f",&matrix[i][j]);
}
fscanf(sample,"\n",&matrix[i][j]);
}
fclose(sample);
可悲的是,代码不起作用..如果我有这个矩阵:
5.00 4.00 5.00 6.00
5.00 4.00 3.00 25.00
5.00 3.00 4.00 23.00
5.00 2.00 352.00 6.00
输入3为行,3为列,我得到:
5.00 4.00 5.00
6.00 5.00 4.00
3.00 25.00 5.00
不仅这不是一个2乘2的子矩阵,但即使我想要前3行和前3列,它也不能正确打印....
我需要从第3行和第3列开始,然后选择2乘2的子矩阵!
我应该最终得到:
4.00 23.00
352.00 6.00
我听说我可以使用fgets和sscanf来实现这一目标。这是我的试用代码:
fgets(garbage,1,fin);
sscanf(garbage,"\n");
但这也不起作用:(
我做错了什么?
请帮忙。 谢谢!
答案 0 :(得分:5)
好的,所以你想读一个大小 n x m 的子矩阵,从位置 x 开始, y 在大小 p x q 的大矩阵中。你需要两件事:
您当前的实现从矩阵的第一个元素开始读取,然后将元素连续读入子矩阵。更新版本:
FILE *sample = fopen("randomfile.txt", "r");
// skip the first y-1 rows
for (i = 0; i < y - 1; i++) {
fscanf(sample, "%*[^\n]\n", &matrix[i][j]);
}
for (i = 0; i < m; i++) {
// skip the first x-1 numbers
for (j = 0; j < x - 1; j++) {
fscanf(sample, "%*f");
}
// read n numbers
for (j = 0; j < n; j++) {
fscanf(sample, "%f", &matrix[i][j]);
}
if (x + n < p) {
// consume the rest of the line
fscanf(sample, "%*[^\n]\n");
}
}
fclose(sample);
更新:从数组中读取子矩阵甚至更简单,只需要更多的计算。要点是,一个大小为 p x q 的矩阵可以存储在一个大小为 p x q 这样矩阵[i,j]可以从数组[i *(j-1)+ j]中读取(大约 - 可能有一个错误,我不知道哪个是列,哪个是排,但希望你明白了: - )
所以代码就像
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
submatrix[i][j] = array[(y + i) * p + x + j];
}
}
答案 1 :(得分:2)
让我们分阶段进行。首先对代码进行一些小修复:
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
float dummy; /* this will make thing easier later */
fscanf(sample,"%f",&dummy);
matrix[i][j] = dummy;
}
/* fscanf(sample,"\n",&matrix[i][j]); this isn't even legal */
}
现在我们定义我们想要的东西:
int startrow = 2; /* The starting index. Remember we index 0,1,2,3 */
int startcol = 2;
int resultrows = 2; /* How many rows we want in our answer */
int resultcols = 2;
float result[resultrows][resultcols];
现在我们忽略了我们不想要的东西:
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
float dummy;
fscanf(sample,"%f",&dummy);
if(i >= startrow && i < startrow + resultrows &&
j >= startcol && j < startcol + resultcols){
matrix[i][j] = dummy;
}
}
}
请注意,现在只有我们想要的值被复制到matrix
,matrix
的其余部分是未初始化的乱码。现在将其写入result
而不是:
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
float dummy;
fscanf(sample,"%f",&dummy);
if(i >= startrow && i < startrow + resultrows &&
j >= startcol && j < startcol + resultcols){
result[i-startrow][j-startcol] = dummy;
}
}
}
修改:
如果要从内存中已有的较大矩阵复制子矩阵,则内循环应为
for(j=0;j<cols;j++){
if(i >= startrow && i < startrow + resultrows &&
j >= startcol && j < startcol + resultcols){
result[i-startrow][j-startcol] = matrix[i][j];
}
}
答案 2 :(得分:1)
诀窍是让编译器将您的特定数组元素视为矩阵的起点;以下代码片段可以做到:
(int(*)[SIZE_OF_2ND_DIM])(&a[4][3])
以下程序捕获了预期目的:
#include <stdio.h>
int num;
void print( int a[][num], int row, int col )
{
int i, j;
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
printf("%3d ", a[i][j]);
printf("\n");
}
}
int main()
{
int a[10][10];
int i, j;
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
a[i][j] = i*10+j;
num = 10;
print(a, 10, 10);
printf("\n\n");
print((int(*)[num])(&a[4][3]), 5, 4);
return 0;
}
以下是相应的输出:
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
43 44 45 46
53 54 55 56
63 64 65 66
73 74 75 76
83 84 85 86