scanf导致分段故障11

scanf导致分段故障11,c,segmentation-fault,C,Segmentation Fault,我的代码运行良好。然后我开始出现分割错误。我试着冲洗缓冲液,但没用。scanf使用一个名为frame_size的int变量,我认为这就是问题所在。有人能帮我解决这个问题吗 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <string.h> int main() { char ref[30]; // array that holds refe

我的代码运行良好。然后我开始出现分割错误。我试着冲洗缓冲液,但没用。scanf使用一个名为frame_size的int变量,我认为这就是问题所在。有人能帮我解决这个问题吗

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

int main() {
    char ref[30];      // array that holds reference string
    int frame_size;    // maximum number of frames is 8
    // a frame holds a number thats in the reference stream.  
    int optimal_fault = 0;
    int lru_fault = 0; // least recently used faults
    int mfu_fault = 0; // most frequently used faults
    int lfu_fault = 0; // least frequently used faults    
    int type = 0;      // initializing to an invalid type in the switch statement
    int pages = 0;     //counts how many times you've looped
    //int page = 0;    //this will be the pages array 
    printf(" Please enter reference string: ");

    //fflush(stdin);    
    fgets(ref, 30, stdin);

    printf(" Please enter the number of frames(no more than 8 allowed)\n");

    scanf("%i[^\n]", &frame_size);

    int len = strlen(ref);
    int result = 0;
    int page[len];
    int i = 0;
    int k = 0;

    while (ref[i] != '0') {
        //page[i] = ref[i] *10 + (ref[i] -'O');
        /* if (ref[i] == ' ') {
            i++;
        }*/
        if (ref[i] != ' ' && ref[i+1] != ' ') {
            page[k] = ref[i] - '0' + (ref[i+1] - '0');  
            printf("page: %d", page[k]);
            k++;
            i++;
        }
        //printf("This is the string and number of frames: %d %i ", page[2],frame_size);
    }
    int frame[frame_size];// initializing frame array
    for (int i = 0; i < frame_size; i++) {
        frame[i] = -1; //which means the element is empty
    }

    //optimal algorithm
    /* for (int i = 0; i < ref.size(); i++) {
        printf("%d",ref.size());
    } */
    return 0;
}

您的代码中存在多个问题:

扫描%i[^\n],&帧大小;在包含换行符之前,不会读取该行的其余部分。要使用scanf执行此操作,应编写:

if (scanf("%i%*[^\n]%*1[\n]", &frame_size) != 1) {
    /* complain about invalid input */
    exit(1);
}
但是使用fgets读取一行并用sscanf解析它要简单得多,特别是因为scanf版本不会处理非数字的初始输入,也不会测试其返回值

这里有一个输入错误:

while (ref[i] != '0')
要在字符串ref的内容上进行迭代,应在'\0'处停止,NUL字节不同于'0',字符0的ASCII值为48

此外,此处从以字符表示的页码到整数值的转换不正确:

    if (ref[i] != ' ' && ref[i+1] != ' ') {
        page[k] = ref[i] - '0' + (ref[i+1] - '0');  
        printf("page: %d", page[k]);
        k++;
        i++;
    }
你应该写以下内容:

for (i = 0; ref[i] != '\0'; i++) {
    if (isdigit((unsigned char)ref[i] && isdigit((unsigned char)ref[i+1])) {
        page[k] = (ref[i] - '0') * 10 + (ref[i+1] - '0');  
        printf("page: %d", page[k]);
        k++;
        i++;
    }
}
您试图实现的实际语义是模糊的,您应该在函数之前在注释中记录它们

还注意到这些建议:

不要在这里发布制表符缩进的代码,它的格式很差。实际上,在代码中使用制表符是一个坏主意,制表符在不同的系统中得到不同的扩展,并导致代码在各种情况下变得不可读,就像这里一样,但在电子邮件中也是如此。我必须重新格式化您的代码来修复它

不要用/**/注释代码块,使用if 0和endif

您的while循环while ref[i]!='“0”仅在它不是“0”时结束-如果它从未找到“0”该怎么办

例如,当输入值为2312312时,while循环将继续在内存中进行,并通过在内存上写入第[]页的界限

如果字符串以两个空格开头,那么while循环中if语句中的条件永远不会为true,那么i仍然==0

因此,您需要添加更好的错误处理,从第一个FGET开始,然后读取帧大小并检查其范围

例如,循环应该有另一个退出条件

for (i = 0; i < len - 1; i+=2)
{
  char s[16];
  if (sscanf(ref + i, "%2[0-9]", s) == 1)
  {
    page[k++] = atoi(s);
  }
}

不要使用scanf,先使用getline,然后使用strtol/strtoul。您如何知道问题出在scanf上?您是否运行了调试器以缩小其范围?页被定义为具有len值。但是,循环变量k在while循环中不受约束地运行,可能会超过len-1。如果ref字符串包含空格,while循环将挂起,因为i将永远不会增加。在最后一个循环上。”ref[i+1]-'0将处理空终止符。这就是你想要的吗?此外,您没有发布SEGFULT之前的输出。此外,没有完成调试的详细信息。另外,还有一个DCV。代码似乎不正确:123将被解析为第12页和第23页。@chqrlie你是正确的,我误解了他的问题,已经更新。仍然不正确:`123`将被错误解析为第23页而不是第12页。如果fscanf找到两位数字的匹配项,则应在循环中增加1,并跳过一个额外字符。请注意,您的代码将接受带有一位数字的数字:我们不知道这是否正确。在这一点上,手工解析更容易。@像123这样的chqrlie输入根本不会设置第[k++]页,因为sscanf在第一次调用时会返回0。@chux:sscanf确实会在第一次调用时返回0,然后i递增2,比较小于3,对sscanf的下一次调用成功地将23解析为s,第[k++]页接收23。次要:如果扫描%i%*[^\n]*1[\n],&帧大小!=1@chux:OP尝试实现的语义未精确指定。如果扫描%i%*[^\n]%*1[\n],&frame\u size!=如果用户输入的数值前面有空格,则1将失败。输入123 1将被解析为值123,行的其余部分将被忽略。这是否是OP所期望的只是我的猜测,我从他伪造的scanf格式%I[^\n]