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

Attempting to read in a file and storing the first input in an array val and the second input in an array wt (weight)

提问人:noobGirlCoding 提问时间:1/27/2020 最后编辑:noobGirlCoding 更新时间:1/27/2020 访问量:222

问:

我需要读取一个名为“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;

当我使用 data.txt 示例中的输入时,它不断输出 55。

C 数组 scanf fopen feof

评论

0赞 kaylum 1/27/2020
您能否详细说明您看到了哪些错误或不正确的行为?“有问题”并不是一个非常翔实的描述。究竟是什么问题?
2赞 kaylum 1/27/2020
为什么“while ( !feof (file) )”总是错的?
0赞 noobGirlCoding 1/27/2020
谢谢,它没有输出任何东西,所以我认为这就是我从文件中存储 val 和 wt 的方式。
0赞 David C. Rankin 1/27/2020
你可以让生活更轻松 然后你可以简单地创建你的数组 现在你可以把每个对象作为一个对象来协调,例如 和 等。一次读取一行,现在你有了填充的结构数组和元素的数量。struct mydata { int val; int wt; };strct mydata arr[20] = {{ .val = 0; }};valwtarr[0].valarr[0].wt;size_t n = 0; while (fscanf(myfile, "%d %d", &arr[n].val, &arr[n].wt) == 2) { n++; }n
0赞 user3629249 1/28/2020
OT:关于:始终检查 (!=NULL) 返回值以确保操作成功。myFile=fopen("data.txt", "r");

答:

2赞 David C. Rankin 1/27/2020 #1

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

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

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

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

每当您将多个值作为单个对象(例如每个和一对)进行协调时,您应该考虑 .这允许您将这两个值作为单个对象进行协调。valwtstruct

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

#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  %2d\n", i, arr[i].val, arr[i].wt);
}

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

示例使用/输出

在文件中使用您的数据时,您将收到以下输出: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

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

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

1赞 Serge Ballesta 1/27/2020 #2

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

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

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

如果你发生了这些台词:

// uncomment next block for debugging
printf("n=%d\n);
for (i = 0; i < n; i++) {
    printf("%d %d\n", 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=%d\n);
for (i = 0; i < n; i++) {
    printf("%d %d\n", wt[i], val[i]);
}
*/