使用sscanf进行解析不会';t保存数组以供后续使用

使用sscanf进行解析不会';t保存数组以供后续使用,c,arrays,parsing,fgets,scanf,C,Arrays,Parsing,Fgets,Scanf,我正在从事一个项目,该项目模拟一个n路关联缓存映射。然而,当试图在后续等式中使用地址[i]数组时,问题就出现了。我想我不明白为什么数组没有被保存。任何帮助都将不胜感激。我不是C代码的高手。现在的问题是读取文件并将这些值扫描到数组中。其他我有信心的事情我都能弄明白 代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> /*global

我正在从事一个项目,该项目模拟一个n路关联缓存映射。然而,当试图在后续等式中使用地址[i]数组时,问题就出现了。我想我不明白为什么数组没有被保存。任何帮助都将不胜感激。我不是C代码的高手。现在的问题是读取文件并将这些值扫描到数组中。其他我有信心的事情我都能弄明白

代码如下:

#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
以下是主存储器和高速缓存的特征:

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
这是解析后数组的输出——在以下for循环中:

    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
如您所见,模式和地址数组的第二次迭代与文件while循环中的不同。我不明白为什么会这样。我尽量用描述性的语言。我也不知道为什么格式没有出现。很抱歉,这会让你更难阅读。再次重申,任何帮助或推动正确的方向将不胜感激

编辑: 输出应为:

    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,数组中的值就不一样了

代码已更新

我看到的第一个错误:

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
我看到的第二个错误是:在
while
循环中,您将所有读取的内容都放在同一个索引
I=0
。为使用
,或在
时正确使用

    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;
    }

使用
MAX\u INPUT\u LINES
而不是
50

你需要做一些工作才能找到一个新的方法。没有人会看你的代码墙。在找出显示您的问题的最小完整示例时,您不仅可以帮助我们,而且很有可能您自己也会发现问题。@davidbak我花了几天时间试图找出问题以及实现目标的不同方法,但仍然无济于事。我知道代码应该做什么,并且我添加了一个正确输出的示例,但是我没有看到问题所在。尽管如此,还是要感谢你的评论。我要说的是与戴维贝克相反的话。代码不是很长,但它不是一个完整且可验证的示例。请提供一个完整的编译程序,并对其进行测试,以确保它能产生您指定输入的输出(有时人们会删除代码以使其变小,并发布一个程序,在他们的问题中没有任何错误)。@jdarthenay我在中添加了其余的代码。它在我的系统上编译。
错误:格式'%s'要求参数类型为'char*',但参数2的类型为'char(*)[50]'[-Werror=format=]
虽然由于我的声誉不高,我无法对你的答案投赞成票,但我衷心感谢你花时间仔细阅读我的代码@jdarthenay我对C没有太多的经验,但是在愿意花一点时间的人们的帮助下,我正在学习!!再次感谢你@如果我的答案解决了你的问题,你应该接受它,它应该在低于我答案分数的地方。
    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