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. これは、使用している 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 に答える
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 に答える