汇编器开发问题:无法在文件指定位置将var修改为label
汇编器符号表修改问题
我正在开发大学实验用的汇编器,需要读取汇编程序生成机器码。构建sym.txt(符号表文件)时,先引用后定义的标签会被存为var类型,我想把文件特定位置的字符串“var”改成“label”,但操作失败。
问题代码
printf("current buffer being checked: %s\n", buf1); printf("Current Position of file pointer: %ld\n", ftell(sym)); //strcpy(curlabel, "label"); fseek(sym, 98, SEEK_SET); // Seek to the position of "var" printf("AFTER SEEK Position of file pointer: %ld\n", ftell(sym)); // Read and verify content at this position (optional for debugging) size_t bytesRead = fread(des, sizeof(char), 6, sym); des[bytesRead] = '\0'; // Null-terminate the string printf("Current pointer string: %s\n", des); // Expecting to see " var 2" // Reset the file pointer to the position where you want to write fseek(sym, 98, SEEK_SET); printf("Position before write: %ld\n", ftell(sym)); // Write "label" at the current position fwrite("label", sizeof(char), 5, sym); // Optional: Flush the changes to disk fflush(sym);
错误输出
N var 2002 ZERO var 2004 COUNT var 2006 SUM var 2008 LOOP label 2008 X var 2010 ONE var 2020 OUTER var 2026 // This line should have been changed to "OUTER label 2028" labelOUTER label 2028 // <- the label string is inserted here
问题原因及解决方法
核心问题
硬编码的偏移量98完全错误,导致文件指针定位到了下一行的开头,写入的"label"直接覆盖了下一行的"OUTER"前缀,形成"labelOUTER"。
解决步骤
- 避免硬编码偏移:不要用固定数字定位,而是通过逐行读取找到目标行,再定位到行内的"var"位置。
- 确认文件打开模式:必须使用
r+模式打开文件(读写模式,保留原有内容),如果用w+会清空文件,a+只能在末尾写入,都会导致异常。 - 正确修改内容:如果需要完整修改为
OUTER label 2028,建议读取整行内容修改后再写回,避免覆盖错位。
修正后的示例代码
方式1:精准定位修改"var"为"label"
// 确保文件以r+模式打开 FILE *sym = fopen("sym.txt", "r+"); if (!sym) { perror("Failed to open file"); return 1; } char line[256]; long target_pos = -1; // 逐行查找包含"OUTER var"的行 fseek(sym, 0, SEEK_SET); while (fgets(line, sizeof(line), sym) != NULL) { if (strstr(line, "OUTER var")) { // 计算当前行的起始位置 long line_start = ftell(sym) - strlen(line); // 找到"var"在该行的偏移 char *var_ptr = strstr(line, "var"); if (var_ptr) { target_pos = line_start + (var_ptr - line); break; } } } if (target_pos != -1) { // 定位到"var"的起始位置 fseek(sym, target_pos, SEEK_SET); // 写入"label"(注意:会覆盖后续2个字符,需根据需求调整) fwrite("label", sizeof(char), 5, sym); fflush(sym); } else { printf("Target line not found\n"); } fclose(sym);
方式2:修改整行内容(包含地址)
如果需要把行完整改为OUTER label 2028,可以读取整行修改后再写回:
FILE *sym = fopen("sym.txt", "r+"); if (!sym) { perror("Failed to open file"); return 1; } char line[256]; long line_start; fseek(sym, 0, SEEK_SET); while (fgets(line, sizeof(line), sym) != NULL) { line_start = ftell(sym) - strlen(line); if (strstr(line, "OUTER var")) { // 替换"var"为"label" char *var_ptr = strstr(line, "var"); if (var_ptr) strncpy(var_ptr, "label", 5); // 替换地址2026为2028 char *addr_ptr = strstr(line, "2026"); if (addr_ptr) strncpy(addr_ptr, "2028", 4); // 定位到行开头,写回修改后的内容 fseek(sym, line_start, SEEK_SET); fputs(line, sym); fflush(sym); break; } } fclose(sym);
内容的提问来源于stack exchange,提问作者SirZechs
相关产品推荐
相关产品推荐

