所以在听了克雷格·埃斯蒂的回答后,我设法得到了以下代码:
#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
为什么现在呢?我找不到与以下答案不同的原因。如果我在答案中执行确切的代码,它会确实返回正确的答案。预先感谢。
答案 0 :(得分:-1)
这是我的主要评论开头。
您不能执行: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;
}
更新:
首先,非常感谢您的工作。查看您的代码(由于完全不同,我无法再调用它了)
是的,它旨在作为您编写/重写自己的代码的指南。
我发现findSize函数基本上无关紧要。
从技术上讲这是正确的,但是会分配比需要更多的空间。
我尝试放置另一个fscanf而不是调用findSize函数,但我不知道此函数的工作原理。
对您确定此替代大小调整算法很有帮助。
让我看看我是否明白:如果有第三个参数,它将每个read元素存储到第三个参数(应该是变量)中。但是,如果没有第三个元素,并且在第二个参数中添加了*,则它不会将读取的元素存储在任何位置。我说的对吗?
信不信由你,我不会过多地使用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);
这会将所有个数字放在相同索引中,即size
,它是{{ 1}}数组,所以这是未定义的行为。
此外,循环条件与其应有的条件相反,因此仅填写一个数字。
要解决此问题,我们需要一个附加的索引变量,并且需要更改numbers
循环的含义:
while
更改后,其余更新的代码[min / max / sum]可以正常工作。
关于样式的一些注释:
您注意到,我原始发布的代码有些不同(例如,将int idx0 = 0;
while (fscanf(fi, "%d", &numbers[idx0]) == 1)
++idx0;
循环替换为while
循环)。
但是,我没有做的一件事是重用了index变量。也就是说,每个循环都不需要有单独的循环。它们都可以更改为单个for
变量。
使用不同的符号并没有错,并且可以更加清晰。但是,idx
,idx
,idx1
的描述性不够。
如果您想保留单独的变量,我建议使用更具描述性的名称,例如:idx2
,inpidx
,minidx
和maxidx