C语言 尝试读取文件并将第一个输入存储在数组 val 中,将第二个输入存储在数组 wt(weight)中



我需要读取一个名为"data.txt"的文件,并将第一个输入存储为值,将第二个相应的输入存储为权重。我在读取它们和存储值时遇到问题。

data.txt (example)
3 25
2 20
1 15
4 40
5 50

这是我开始的:

FILE *myFile;
myFile=fopen("data.txt", "r");

int val[20]={0}; //initialize value array to zero
int wt[20]={0}; 
int W=80; //Set capacity to 80
int i;
int n;
while(!feof(myFile)){ 
fscanf(myFile, "%1d%1d", &val[i], &wt[i]);
}
n = sizeof(val)/sizeof(val[0]);
printf("%d", knapSack(W, wt, val, n));//prints out the maximum value
fclose(myFile);
return 0;

我已将上面的代码编辑为以下内容:

FILE *myFile;
myFile=fopen("data.txt", "r");

int val[20]={0};
int wt[20]={0};
int W=80; //Set capacity to 80
int i;
int n;
for(i=0;i<sizeof(val);i++){
fscanf(myFile, "%1d%1d", &wt[i],&val[i]);
}
n = sizeof(val)/sizeof(val[0]);
printf("%d", knapSack(W, wt, val, n));//prints out the maximum value
fclose(myFile);
return 0;

例如,当我使用数据输入时,它会不断输出 55.txt。

你遇到的最大问题是你没有通过读取本身的返回来控制你的读取循环。例如,在您的情况下,您需要:

int i = 0;
while (fscanf(myFile, "%1d%1d", &wt[i],&val[i]) == 2)
i++;

在读取结束时,i将保存读取到数组中的元素数。

(注意:除非您检查返回,否则您无法正确使用任何输入函数...

而不是将值读取到单独的数组中,每当您将多个值作为单个对象进行协调时(例如,每个valwt对(,您应该考虑struct。这允许您将这两个值作为单个对象进行协调。

在您的案例中,一个简单的示例可能是:

#include <stdio.h>
#define MAXVAL 20   /* if you need a constant, #define one (or more) */
typedef struct {    /* struct with int val, wt + typdef for conveninece */
int val, wt;
} mydata;
int main (int argc, char **argv) {
size_t n = 0;                           /* number of elements read */
mydata arr[MAXVAL] = {{ .val = 0 }};    /* array of mydtata */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {  /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* read all pairs of values in file into array */
while (fscanf (fp, "%d %d", &arr[n].val, &arr[n].wt) == 2)
n++;
if (fp != stdin)   /* close file if not stdin */
fclose (fp);
for (size_t i = 0; i < n; i++)  /* output values */
printf ("arr[%zu]  %2d  %2dn", i, arr[i].val, arr[i].wt);
}

上面,代码的作用与我在从文件中成功读取一对值时对读取循环进行调节时建议的相同。唯一的区别是协调结构中的val值和wt值。

示例使用/输出

将数据放在文件dat/val_wt.txt中,您将收到以下输出:

$ ./bin/read_val_wt dat/val_wt.txt
arr[0]   3  25
arr[1]   2  20
arr[2]   1  15
arr[3]   4  40
arr[4]   5  50

虽然上面我们直接使用fscanf读取,您可以通过先将每一行读取到字符数组中,然后使用sscanf解析字符数组中的所需值来使您的读取更加健壮。您本质上在做同样的事情,但是通过使用fgets/sscanf您可以对 (1( 行的读取进行独立验证;(2(从行中解析所需信息。如果行格式不正确,则可以防止匹配失败影响输入文件中其余行的读取。

仔细查看,如果您有其他问题,请告诉我。

哎呀,这里有很多小问题...

首先,即使不相关,您也始终无法检查输入函数的结果。它可能导致隐藏问题...

接下来,规则是当您没有得到预期时,跟踪中间值

你有没有发生过这些台词:

// uncomment next block for debugging
printf("n=%dn);
for (i = 0; i < n; i++) {
printf("%d %dn", wt[i], val[i]);
}

你会看到

n = 20
3 2
5 2
2 0
1 1
5 4
4 0
5 5
0

显示:

  • n 是 20(不确定你是否预料到(
  • 您一次读取一个数字而不是一个整数值的值(由于%1d格式(

我的建议:

for (i = 0; i<sizeof(val); i++) {        // do not try to read more than array capacity
if (2 != fscanf(myFile, "%d%d", &wt[i], &val[i])) break;  // stop when no more data
}
n = i;     // number of actual values
// uncomment next block for debugging
/*
printf("n=%dn);
for (i = 0; i < n; i++) {
printf("%d %dn", wt[i], val[i]);
}
*/

最新更新