0

我希望你能帮助我解决一些我不确定的事情,即使编译器没有抱怨它们:

在这里我需要编写一个获取输入和输出的程序,在输入文件中存储了我不知道它们的数量除以空格的整数,我需要读取这些数字,按数字总和比较对它们进行排序并打印出来输出文件中的排序数字。这就是我写的,然后是关于这段代码的几个简短问题:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>


int myComp(const void *a, const void *b){

    int x=(*(int*)a);
    int y=(*(int*)b);
    int sumForx=0;
    int sumFory=0;

    while (x){
        sumForx=sumForx+(x%10);
        x=(x-(x%10))/10;
    }

    while (y){
            sumFory=sumFory+(y%10);
            y=(y-(y%10))/10;
        }
    if (x>y) return 1;
    else if (x<y) return -1;
    else return 0;



}

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

    FILE* inFile;
    FILE* outFile;
    int size=0;
    int tmp;

    if (argc!=3) {
        printf("Please enter 3 arguments");
        assert(0);
    }
    inFile=fopen(argv[1], "r");
    if (inFile==NULL) {
        printf("path to the input file has not found");
        assert(0);
    }
    outFile=fopen(argv[2], "w");

    if (outFile==NULL) {
        printf("path to the output file has not found");
        assert(0);
    }

    while (fscanf(inFile, "%d", &tmp)==1) {
        size++;
    }

    int arr[size];

    fseek(inFile, 0, SEEK_SET);
    int i=0;
    while (fscanf(inFile, "%d", &tmp)==1) {
        arr[0]=tmp;
        i++;
    }

    qsort(arr,size,sizeof(int),myComp);

    int j;
    for (j=0;j<size;j++){
        fprintf(outFile,"%d",arr[j]);
        fprintf(outFile,"%c",' ');
    }

    fclose(inFile);
    fclose(outFile);

    return 1;

}
  1. 我在主程序中不断定义新变量,在不同的地方——我记得我不应该这样做,因为所有变量都必须在函数的开头定义,除非有内部函数/括号的局部变量,这是这里不是这种情况——但编译器仍然可以接受——正确的做法是什么?

  2. 如果 (1) 的答案是“你必须在函数的开头定义所有变量”——在我的情况下,我必须int* arr在计算大小后定义动态并为其分配空间,否则我不能使用int arr[size],因为计算了大小在所有变量都已经定义之后,包括整数数组。

3.我想在打印到文件时在这些数字之间输入一个空格,fprintf(outFile,"%c",' ');每次输入整数后是否正确?

4.欢迎任何其他更正!

4

5 回答 5

1

在函数开头声明所有变量的要求可以追溯到标准的先前版本(C89,C99 已过时,C11 已过时)。

由于您使用的是可变长度数组 ( arr[size]),这在该标准的先前版本中是不可能的,因此您显然使用了一个中等体面的编译器,它不会遵守自 1999 年以来不再适用的限制。 -)

至于打印一个空间,fprintf( outfile, " " )或者(甚至更好)fputc( ' ', outfile )会做。

至于进一步的更正,我有不阅读/评论未注释来源的习惯。你有一种我强烈反对的编码风格,但至少你在应用它时是一致的。;-)

于 2012-09-17T08:48:14.880 回答
0

1:只要您使用的是支持 C99 标准或更高版本的编译器,就可以在函数体的任何位置声明变量。正如您所说,早期的编译器要求您在块范围的开头声明变量。

但是,通过进一步限制某些变量的范围,您可以做得比在您的代码中做得更好。代替:

int j;
for (j = 0; j < size; j++) { ... }

您可以将其简化为:

for (int j = 0; j < size; j++) { ... }

这也限制了语句j后面的块可访问的范围。for

2:动态大小的数组仅在 C99 及更高版本中受支持,因此代码不会在不支持较新标准的编译器上编译。

3:您可以简单地在初始格式字符串中添加额外的空格:

fprintf(outfile, "%d ", arr[j]);
于 2012-09-17T08:56:17.163 回答
0
  1. 这取决于您使用的 C 版本。如果您使用 ANSI C (c89),您将收到有关此问题的警告或错误。但是大多数(如果不是全部)现代编译器几乎在代码的任何地方都支持声明。
  2. 这又取决于您的编译器。旧的编译器不能像这样分配静态数组,现代编译器可以。
  3. fprintf(outFile, " ");也是完全合法的。
于 2012-09-17T08:36:50.990 回答
0
printf("Please enter 3 arguments");

可执行文件名称通常不称为参数,因此通常是

printf("Please enter 2 arguments - input filename and output filename e.g.:\n");
printf("%s file1.txt file2.txt\n",argv[0]);

这个

arr[0]=tmp;

应该

arr[i]=tmp;
于 2012-09-17T09:48:32.823 回答
0
  1. 如果您使用 gcc,它将允许您将变量放在函数中的任何位置。然而,其他编译器(例如 MSVC 2008)遵循ansi c ie c89 并且可能会抱怨它。正确的做法取决于您的应用程序。如果您希望它可以跨编译器移植,则声明应位于语句之前。
  2. 这也是特定于编译器和 C 标准的,因此类似于第 1 点的推理适用。
  3. 为此,您的代码看起来不错,但我使用类似:

    fprintf(outFile, "%d ", arr[j]);

在一行中实现类似的功能。

于 2012-09-17T08:53:13.083 回答