c-分段故障11混淆



我的任务是读取一个test.m文件,对其进行解析,并将相关信息放入一个类型语句数组中(我创建了该数组)。我已经完成了大部分作业。唯一错误的是,我在输出的最后得到了一个Segmentation Fault 11。我想这可能是我正在做的输出部分出了问题,所以我评论了一下。它仍然给了我一个seg错误。无论我评论什么,它总是在程序的最后给我一个seg错误。我很困惑是什么原因造成的。我该怎么办?既然其他一切都在起作用,我应该忽略它吗?

这是代码

#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 availablen");
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 :: %sn", 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 = %sn", localspot, token);
token = strtok(NULL, space);
}
// starting point check
else if (strcmp(token, "EP:") == 0) {
token = strtok(NULL, space);
EP = atoi(token);
//printf("nEP: %in", EP);
}
// label check
else if (strcmp(str, ":") == 0) {
//printf("--Label found :: %sn", token);
strcpy(states[linetotal].label, token);
token = strtok(NULL, space);
}
// a function
else if ((strcmp(token, "") != 0) && (strcmp(token, "n") != 0)){
//printf("Function :: %sn", 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 :: %sn", token);
}
token = strtok(NULL, space);
linetotal++;
}
else
break;
} 
// the output process
printf("System State:n-------------n");
printf("prog.PC: %in", EP);
printf("Number of locals: %in", localspot);
for (int i = 0; i < localspot; i++) 
printf("Local %i: %in", i, locals[i]);
printf("prog.PROGSIZE: %inn", linetotal);
printf("       Program      n--------------------nn");
for (int i = 0; i < linetotal; i++) 
printf("%.6s %.5s %.6sn", states[i].label, states[i].opcode, states[i].arg);
fclose(ifp);
return(0);
}

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

您还应该注意WhozCraig所说的内容,并使您的str足够大,这也意味着为终止的null字符保留一个额外的字符。为缓冲区大小定义一个常量是个好主意,但您应该在整个程序中一致地使用它。

无论如何:null终止您的字符串。fread返回读取成功的项目,因此:

char str[FREAD_SIZE + 1];
int n;
/* ... */
n = fread(str, 1. FREAD_SIZE, ifp);
if (n < 0) exit(1);
str[n] = '';

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

编辑:字符缓冲区str当然必须足够大,才能容纳其他终止的''。否则,如果读取了最大字符数,则设置str[n]将写入缓冲区之外。(感谢WhozCraig发现了这一点。我自己真的应该知道。)

相关内容

  • 没有找到相关文章

最新更新