2016-04-27 9 views
-1

私は、nウェイ連想キャッシュマッピングをシミュレートするプロジェクトを進めています。しかし、この問題は、後の方程式でaddress [i]配列を使用しようとするときに発生します。私は配列が保存されていない理由を理解していないと思います。どんな助けも非常に高く評価されるでしょう。私はCのコーディングでは最善ではない。今問題は、ファイルから読み込み、それらの値を配列にスキャンすることです。他のすべて私は私が把握することができると確信しています。ここでsscanfを使用した解析では、その後の使用のために配列が保存されません

はコードです:

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


/*global variables */ 
int mainSize, cacheSize, blockSize, cmSet, cnumBlocks, mnumBlocks,address[50],mmBlkNum[50], mappedCMset[50],hit_miss[50],address[50]; 
char mode[50]; 
int totMemRefs=0; 


int main(void) 
{ 
    /*Variables */ 

    int i; 
    char replacePolicy; 
    char filename[50]; 
    char *result = NULL; 
    char line[50]; 
    FILE *fp; 
    fp = fopen(filename, "r"); 


    /*Gathers input from user */ 
    printf("Enter the main memory size between between 4 and 32K bytes: "); 
    scanf("%d",&mainSize); 
    if (mainSize < 4 || mainSize > 32768) 
    { 
     printf("Invalid main memory size."); 
     //errorCheck() 
    } 

    printf("Enter the size of the cache between 2 and 32K bytes: "); 
    scanf("%d", &cacheSize); 
    if (cacheSize < 2 || cacheSize > 32768) 
    { 
     printf("Invalid cache memory size."); 
     //errorCheck() 
    } 


    printf("Enter the size of the block/line between 2 and 32K bytes: "); 
    scanf("%d",&blockSize); 
    if (blockSize < 2 || blockSize > 32768) 
    { 
     printf("Invalid block/line size."); 
     //errorCheck 
    } 

    printf("Enter the degree of set-associativity: "); 
    scanf("%d", &cmSet); 


    cnumBlocks = cacheSize/blockSize; 
    printf("Number of blocks in cache = %d\n", cnumBlocks); 

    mnumBlocks = mainSize/blockSize; 
    printf("Number of blocks in main memory = %d\n", mnumBlocks); 

    printf("Enter replacement policy (L = LRU, F = FIFO): "); 
    scanf("%s", &replacePolicy); 




    printf("Enter the name of the file containing the list of memory referenced: "); 
    scanf("%s", filename); 


    /* checks if filename is valid/exits */ 
    if ((fp = fopen(filename, "r")) == NULL) 
    { 
     printf("Invalid input."); 
     //errorCheck(); 
    } 

    /* gets total number of mem references from first line of file and stores in variable totMemRefs*/ 
    fgets(line,sizeof(line),fp); 
    result = strtok(line,"\n"); 
    totMemRefs = atoi(result); 
    printf("Total Mem Refs = %d\n", totMemRefs); 


    /*skips second line of white space */ 
    fgets(line, sizeof(line),fp); 

    i=0; 
    //reads each line of file and tokenizes into mode and address 
    while (fgets(line, sizeof(line), fp)!=NULL) 
    { 

     if (sscanf(line,"%s %d",&mode[i],&address[i]) == 2) 
     { 
      printf("Mode: %c Address: %d\n",mode[i],address[i]); 
      i++; 
     } 


    }//end of parsing while loop 

    fclose(fp); //close file after reading 


    for (i=0; i<totMemRefs; i++) 
    { 
     /* calculates the corresponding block number of the address */ 
     mmBlkNum[i]=address[i]/blockSize; 

     /* calculates the corresponding cache mem set that mm block is in */ 
     mappedCMset[i]=mmBlkNum[i]%cnumBlocks; 
     printf("Mode = %c Address = %d MM Block Num = %d Cm Set = %d\n", mode[i],address[i],mmBlkNum[i],mappedCMset[i]); 

    } 

}//end of main 

これはexample_test_data.txtの内容です:

6 

R 0 
R 1 
R 4 
R 36 
R 0 
R 4 

これらはメインメモリとキャッシュメモリの特徴である:

main mem size = 128 bytes 
cache mem size = 32 bytes 
block size = 4 bytes 
set associativity = 2 
filename = example_test_data.txt 

これはwhileループ内の配列の出力です:

Mode: R Address: 0 
    Mode: R Address: 1 
    Mode: R Address: 4 
    Mode: R Address: 36 
    Mode: R Address: 0 
    Mode: R Address: 4 

これは、解析した後の配列のために出力されます - ループのために、以下に:

Mode = R Address = 4 MM Block Num = 1 Cm Set = 1 
    Mode = Address = 0 MM Block Num = 0 Cm Set = 0 
    Mode = Address = 0 MM Block Num = 0 Cm Set = 0 
    Mode = Address = 0 MM Block Num = 0 Cm Set = 0 
    Mode = Address = 0 MM Block Num = 0 Cm Set = 0 
    Mode = Address = 0 MM Block Num = 0 Cm Set = 0 

あなたが見ることができるように、モードやアドレスの配列の2回目の反復が同じではありませんファイル中のものはwhileループです。私はなぜこれが当てはまるのか混乱しています。私は可能な限り説明的であるように努めた。私はまた、フォーマットがなぜ現れなかったのかも知らない。申し訳ありませんが、それは読むのが難しくなります。再度、正しい方向への助けやプッシュは大いに感謝されます!

EDIT: 出力は次のようになります。

Mode = R Address = 0 MM Blk Num = 0 CM Set = 0 
    Mode = R Address = 1 MM Blk Num = 0 CM Set = 0 
    Mode = R Address = 4 MM Blk Num = 1 CM Set = 1 
    Mode = R Address = 36 MM Blk Num = 9 CM Set = 1 
    Mode = R Address = 0 MM Blk Num = 0 CM Set = 0 
    Mode = R Address = 4 MM Blk Num = 1 CM Set = 1 

私は正しい値を取得する必要があります方程式を知っています。私は手でこれらの問題を解決する方法を知っている。結果が何であるかを知ることは問題ではありません。 以前は、fscanfとstrtokを使っていましたが、どちらも希望の結果を出していませんでした。基本的には、私はスキャンしているwhileループでそれを印刷するときに動作しますが、mmBlkNumとmappedCMsetを計算しようとすると、配列の値は同じではありません。

コードが更新されました。私が見

+0

[最小限の完全で検証可能な例](http://stackoverflow.com/help/mcve)を考え出すには、いくつかの作業が必要です。誰もあなたのコードの壁を見るつもりはありません。あなたの問題を示す最小限の完全な例を見つけ出すことで、私たちを助けるだけでなく、自分で問題を見つける良いチャンスがあります。 – davidbak

+0

@davidbak私は、目標を達成するためのさまざまな方法だけでなく、問題を把握するのに多くの時間を費やしましたが、依然として無駄です。私はコードが何をすべきかを知っており、正しい出力の例を追加しましたが、私は問題を見ていません。それにもかかわらず、コメントありがとうございます。 – Tmphillips

+0

私はdavidbakとは反対に言うでしょう。コードはそれほど長くはありませんが、完全で検証可能な例ではありません。コンパイルする**フル**プログラムを提供してください。あなたが指定した入力で指定した出力を確実に生成することをテストしました(人がコードを削除してエラーを起こさないようにする)。 – jdarthenay

答えて

0

まずエラー:

scanf("%s", &filename); 

が正しい引数で置き換え:

scanf("%s", filename); 

ので、これらのものは、コンパイラによって言われる-Wallでコンパイルしてください。 -Werrorと組み合わせてください。 -Wextraもお勧めします。あなたのプログラムで

私のコンパイラ出力:私は見

stackoverflow.c: In function 'main': 
stackoverflow.c:246:11: error: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[50]' [-Werror=format=] 
    scanf("%s", &filename); 
     ^
cc1.exe: all warnings being treated as errors 

2番目のエラー:あなたのwhileループ内で同じインデックスi = 0であなたが読んですべてを置きます。どちらかforを使用するか、正しくwhileを使用します。

i = 0; 
    while (fgets(line, sizeof(line), fp)!=NULL && i < totMemRefs) 
    { 
     if (sscanf(line,"%s %d",&mode[i],&address[i]) == 2) 
     { 
      printf("Mode: %c Address: %d\n",mode[i],address[i]); 
      i++; 
     } 


    }//end of parsing while loop 

    if (i < totMemRefs) 
    { 
     fprintf(stderr, "Missing inputs.\n"); 
     return 1; 
    } 

はまた、私は、検証入力は、ユーザは、彼が提供し、検証、ユーザーがすべての行を提供した入力の数を超えない追加。

#define MAX_INPUT_LINES 50 

50の代わりにMAX_INPUT_LINESを使用します。プログラムの先頭でそのような何かを追加することを検討してください。

+0

私は評判が低いためにあなたの答えを投票することはできませんが、私はコードに踏み込んで時間をかけてくれてありがとう! @jdarthenay私はCでの経験はあまりありませんが、少し時間を費やしてくれる人たちの助けを借りて、私は学んでいます!!ありがとうございました! – Tmphillips

+0

@Tmphillips私の答えがあなたの問題を解決するなら、あなたはそれを受け入れることになっています。それは私の答えのスコアのどこかにあるはずです。 – jdarthenay

関連する問題