gpt4 book ai didi

c - 为什么我的代码没有从文件中读取正确的整数?

转载 作者:行者123 更新时间:2023-11-30 20:42:08 25 4
gpt4 key购买 nike

因此,在稍微研究了一下 Craig Estey 的答案后,我设法得到了以下代码:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main(int argc,char **argv){
char *filename = argv[1];
if(filename == NULL) {
printf("Please specify a filename.\n");
exit(1);
}
FILE *fi = fopen(filename,"r");
printf("Finding size...\n");
int size = 0;
while(fscanf(fi,"%*d") != -1) size++;
rewind(fi);
int numbers[size];
while(fscanf(fi,"%d",&numbers[size]) != 1);
fclose(fi);
printf("Size of array: %d\n\n", size);
int idx=0,idx2=1,idx3=1,idx4=1;
printf("Elements: \n");
while (idx < size){
printf("%d\n",numbers[idx]);
idx++;
}
int maximum = numbers[0];
while (idx2 < size){
if (numbers[idx2] > maximum){
maximum = numbers[idx2];
}
idx2++;
}
printf("\nMax: %d\n",maximum);
int minimum = numbers[0];
while (idx3 < size){
if (numbers[idx3] < minimum){
minimum = numbers[idx3];
}
idx3++;
}
printf("Min: %d\n",minimum);
int sum = numbers[0];
while (idx4 < size){
sum = sum + numbers[idx4];
idx4++;
}
printf("Total: %d\n",sum);
}

问题是,现在它执行时不会停止,但仍然没有提供正确的答案。我的“abcd.txt”文件包含以下数字:

5564

4324

863

98743

但是,执行reader.c后我的结果是:

./reader abcd.txt
Finding size...
Size of array: 4

Elements:
0
0
1384783917
32713

Max: 1384783917
Min: 0
Total: 1384816630

现在为什么会这样?我找不到为什么它与下面的答案不同。如果我执行答案中的确切代码,它确实会返回正确的答案。提前致谢。

最佳答案

这是我的热门评论的序言。

你不能这样做:printf(numbers[idx2]);(即第一个参数必须是格式字符串)。因此,请执行以下操作: printf("%d\n",numbers[idx2]);

执行sizeof(numbers)/sizeof(int)不能给出实际填写的数字的准确计数。它给出了最大值,最后会有垃圾值。

因为错误太多,无法一一列举。我必须完全重构你的代码。只需将其详细与您的进行比较即可看到差异。与尝试修补已有的内容相比,您会学到更多、更快的知识。

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

long int
findSize(char *filename)
{
FILE *fp = fopen(filename, "r");

if (fp == NULL) {
printf("findSize: unable to open file '%s' -- %s\n",
filename,strerror(errno));
exit(1);
}

fseek(fp, 0L, SEEK_END);
long int res = ftell(fp);

fclose(fp);
return res;
}

int
main(int argc, char **argv)
{

char *filename = argv[1];
if (filename == NULL) {
printf("please specify a filename\n");
exit(1);
}

printf("findSize\n");
int numbers[findSize(filename)];

printf("scanf\n");
FILE *fi = fopen(filename,"r");
int size = 0;
while (1) {
if (fscanf(fi,"%d",&numbers[size]) != 1)
break;
printf("scanf: %d\n",numbers[size]);
++size;
}
fclose(fi);

printf("size: %d\n",size);
for (int idx2 = 0; idx2 < size; ++idx2)
printf("%d\n",numbers[idx2]);

int maximum = numbers[0];
for (int idx3 = 1; idx3 < size; ++idx3) {
if (numbers[idx3] > maximum)
maximum = numbers[idx3];
}
printf("Max: %d\n", maximum);

int minimum = numbers[0];
for (int idx4 = 1; idx4 < size; ++idx4) {
if (numbers[idx4] < minimum)
minimum = numbers[idx4];
}
printf("Min: %d\n", minimum);

int sum = 0;
for (int idx5 = 0; idx5 < size; ++idx5)
sum = sum + numbers[idx5];
printf("Total: %d\n", sum);

return 0;
}
<小时/>

更新:

First of all, thanks a lot for your work. Looking at your code (I cannot call it anymore my code as it's completely different)

是的,它的目的是指导您编写/重写您自己的代码,您已经完成了。

I see that the findSize function is mostly irrelevant.

这在技术上是正确的,但会分配比所需更多的空间。

I tried to put another fscanf instead of calling a findSize function, but I don't know how this function works exactly.

对于您了解这种替代大小调整算法很有帮助。

Let me see if I get it: If there is a third argument, it stores each read element into the third argument (which should be a variable). But if there is no third element, and you put an * in the second argument, it doesn't store the read elements anywhere. Am I right?

不管你信不信,我不经常使用 fscanf 因为它可能很慢,所以我不熟悉一些更深奥的选项。我已经测试了您的新尺寸调整环,它似乎有效,所以我认为您的分析可能是正确的。

此外,我们可以简单地引入一个额外的标量 int 变量并执行以下操作:

int size = 0;
while (1) {
int val;
if (fscanf(fi,"%d",&val) != 1)
break;
++size;
}
<小时/>

但是,用于读取数字的实际第二个 fscanf 循环将无法工作:

while (fscanf(fi, "%d", &numbers[size]) != 1);

这会将所有数字放入相同索引中,即大小,它超出末尾numbers 数组,因此这是未定义的行为。

此外,循环条件与应有的相反,因此只会填充一个数字。

为了解决这个问题,我们需要一个额外的索引变量,并且需要更改 while 循环的含义:

int idx0 = 0;
while (fscanf(fi, "%d", &numbers[idx0]) == 1)
++idx0;

进行此更改后,更新后的代码的其余部分 [min/max/sum] 可以正常工作。

<小时/>

关于风格的一些注释:

正如您所注意到的,我的原始发布的代码有点不同(例如,用 for 循环替换 while 循环)。

但是,我没有做的一件事是重用索引变量。也就是说,不需要为每个循环设置单独的循环。它们都可以更改为单个 idx 变量。

使用不同的符号并没有错,并且可以增加清晰度。但是,idxidx1idx2 并没有达到应有的描述性。

如果您想保留单独的变量,我建议使用更具描述性的名称,例如:inpidxminidxmaxidx、和 sumidx

关于c - 为什么我的代码没有从文件中读取正确的整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54030811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com