首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分割故障11混淆

分割故障11混淆
EN

Stack Overflow用户
提问于 2014-03-02 08:11:57
回答 1查看 121关注 0票数 0

我的任务是在test.m文件中读取,解析它,并将相关信息放入一个类型语句数组(我创建了该语句)。我大部分时间都完成了这项任务。唯一错误的地方是,我在输出的末尾得到了一个分段错误11。我认为我正在做的输出部分可能有问题,所以我将其注释掉以查看。这还是让我出了个小毛病。无论我评论什么,它总是在程序的末尾给我一个错误。我很困惑是什么导致了这一切。我该怎么办?既然其他一切都正常,我应该忽略它吗?

这是代码

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LC_SIZE 16
#define FREAD_SIZE 1024
#define STATES_SIZE 1024

FILE *ifp;
int linetotal;
int locals[LC_SIZE];
int localspot = 0; // localspot = # of locals
int EP;

typedef char STRING[256];

typedef struct {
  STRING label;
  STRING opcode;
  STRING arg;
} statement;

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

  //statement states[STATES_SIZE] = {"(NULL)"};

  char str[256];
  const char newline[3] = "\n";
  const char space[2] = " ";
  char *token;
  unsigned long length;

  ifp = (argc > 1) ? fopen(argv[1], "r") : NULL;

  if (ifp == NULL) {
    printf("Input file not available\n");
    return -1; }

  fread(str, FREAD_SIZE, 1, ifp);

  token = strtok(str, space);

  statement states[STATES_SIZE];
   for (int i = 0; i < STATES_SIZE; i++) {
    strcpy(states[i].label, "(null)");
    strcpy(states[i].opcode, "(null)");
    strcpy(states[i].arg, "(null)"); }

  while (token != NULL) {

    length = strlen(token);
    if (length > 1 ) { strcpy(str, &token[length-1]); }

    // comment check
    if ((strncmp(token, "/", 1) == 0) || (strcmp(str, "/") == 0)) {
      token = strtok(NULL, newline);
      //printf("Comment :: %s\n", token);
      token = strtok(NULL, space);
    }

    // local check
    else if (strcmp(token, "LC:") == 0) { 
      token = strtok(NULL, space);
      //printf("==LC here==\n");
      locals[localspot] = atoi(token);
      localspot++;
      //printf("Local variable %i = %s\n", localspot, token);
      token = strtok(NULL, space);
    }

    // starting point check
    else if (strcmp(token, "EP:") == 0) {
      token = strtok(NULL, space);
      EP = atoi(token);
      //printf("\nEP: %i\n", EP);
    }

    // label check
    else if (strcmp(str, ":") == 0) {
      //printf("--Label found :: %s\n", token);
      strcpy(states[linetotal].label, token);
      token = strtok(NULL, space);
    }

    // a function
    else if ((strcmp(token, "") != 0) && (strcmp(token, "\n") != 0)){
      //printf("Function :: %s\n", token);
      strcpy(states[linetotal].opcode, token);
      if ((strcmp(token, "halt") != 0) && (strcmp(token, "mul") != 0) && (strcmp(token,     "sub") != 0)) {
        token = strtok(NULL, space); 
        strcpy(states[linetotal].arg, token);
        //printf("arg :: %s\n", token);
      }
      token = strtok(NULL, space);
      linetotal++;
    }
    else
      break;
  } 

  // the output process
  printf("System State:\n-------------\n");
  printf("prog.PC: %i\n", EP);
  printf("Number of locals: %i\n", localspot);
  for (int i = 0; i < localspot; i++) 
    printf("Local %i: %i\n", i, locals[i]);
  printf("prog.PROGSIZE: %i\n\n", linetotal);

  printf("       Program      \n--------------------\n\n");
  for (int i = 0; i < linetotal; i++) 
    printf("%.6s %.5s %.6s\n", states[i].label, states[i].opcode, states[i].arg);

  fclose(ifp);
  return(0);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-02 08:40:12

使用fread,您可以从文件中读取原始数据。这意味着您读取的字符串不是以空结尾的。所有strxxx函数都对以空结尾的字符串进行操作。因为str不是以空结尾的,所以它们将实际数据后的垃圾作为字符串的一部分--长度未定。

您还应该注意WhozCraig说了什么,并使您的str足够大,这也意味着为终止空字符预留一个额外的字符。为缓冲区大小定义常量是个好主意,但您应该在整个程序中始终使用它。

总之:空-终止您的字符串。fread返回已成功读取的项,因此:

代码语言:javascript
运行
复制
char str[FREAD_SIZE + 1];
int n;

/* ... */

n = fread(str, 1. FREAD_SIZE, ifp);
if (n < 0) exit(1);
str[n] = '\0';

请注意,我已将第二个和第三个参数交换给fread。第二个是每个项目的大小,这里是一个char。第三个是要读取的最大项目数。返回值将取决于此,因为它返回读取的项数,而不是读取的字节数。

编辑:当然,char缓冲区str必须足够大以保持终止'\0'。否则,如果读取最大字符数,设置str[n]将写入缓冲区之外。(感谢WhozCraig注意到这一点。我真该想到这一点的。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22125332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档