提问人:username 提问时间:11/12/2023 更新时间:11/13/2023 访问量:58
创建新字符串以某种方式更改旧字符串的值? |C
Creating new string somehow changing value of old string? | C
问:
所以我正在 nand2tetris 中做项目 6 - 你必须在其中制作一个 HACK 汇编器。
现在,我想做的就是创建一个大字符串,将数据存储在程序集文件中,没有 Windows 0x0d和复制新行(所以没有0x0a后跟0x0a)。
这是我的头文件 - assembler.h
typedef struct string
{
int length;
char *the_string;
} string;
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iso646.h>
#include <string.h>
#include "assembler.h"
string *put_the_entire_file_into_one_big_string(FILE *the_entire_file);
string *take_out_the_double_lines(string *the_string);
int main(int argc, char *argv[])
{
// Check the number of arguements
if (argc != 2)
{
printf("Provide only one arguement: the name of the assembly file\n");
return -1;
}
// Check if the arguement is an .asm file
int a = sizeof(argv[1]);
if (!((argv[1][a - 5] == '.') and (argv[1][a - 4] == 'a') and (argv[1][a - 3] == 's') and (argv[1][a - 2] == 'm')))
{
printf("not an .asm file\n");
return -1;
}
// Check if the file exists
FILE *the_file = fopen(argv[1], "r");
if (the_file == NULL)
{
printf("File doesn't exist. Maybe you mistyped it?");
return -1;
}
string *the_big_string_thats_the_entire_file = put_the_entire_file_into_one_big_string(the_file);
string *the_big_string_but_without_mulitple_line_breaks_in_a_row = take_out_the_double_lines(the_big_string_thats_the_entire_file);
free(the_big_string_thats_the_entire_file->the_string);
printf("%s", the_big_string_but_without_mulitple_line_breaks_in_a_row->the_string);
free(the_big_string_but_without_mulitple_line_breaks_in_a_row->the_string);
fclose(the_file);
}
string *put_the_entire_file_into_one_big_string(FILE *the_entire_file)
{
string *one_big_string;
one_big_string->the_string = malloc(sizeof(char));
one_big_string->length = 0;
char c;
while (1)
{
c = fgetc(the_entire_file);
if (c == EOF)
{
break;
}
if (c == 0x0d)
{
continue;
}
one_big_string->the_string[one_big_string->length] = c;
one_big_string->length++;
one_big_string->the_string = realloc(one_big_string->the_string, sizeof(char) * (one_big_string->length + 1));
}
return one_big_string;
}
string *take_out_the_double_lines(string *the_old_string)
{
string *new_string;
new_string->the_string = malloc(sizeof(char));
new_string->length = 1;
new_string->the_string[0] = the_old_string->the_string[0];
new_string->length = 2;
new_string->the_string = realloc(new_string->the_string, sizeof(char) * 2);
for (int i = 1; i < the_old_string->length; i++)
{
printf("%i\t%i\n", i, the_old_string->length);
if (not(the_old_string->the_string[i] == 0x0a and the_old_string->the_string[i - 1] == 0x0a))
{
new_string->the_string[i] = the_old_string->the_string[i];
new_string->length++;
new_string->the_string = realloc(new_string->the_string, sizeof(char) * new_string->length);
}
}
return new_string;
}
根据 gdb,该行
new_string->length = 1;
以某种方式改变the_old_string?
我正在测试的 Add.asm 文件在这里:
https://drive.google.com/file/d/1xZzcMIUETv3u3sdpM_oTJSTetpVee3KZ/view
在 projects/06/Add.asm 下
答:
3赞
Harith
11/12/2023
#1
int a = sizeof(argv[1]);
sizeof
On a 指针返回指针的大小,而不是指向的数据。您需要计算此处的长度。请注意,在访问它之前,您需要先确定它是否有效。strlen()
argv[1]
argv[1][a-5]
或者,您可以使用 和 检查是否以 :strcchr()
strcmp()
argv[1]
".asm"
const char *const point = strcchr(argv[1], '.');
if (point && !strcmp(point, ".asm")) {
/* The file ends with .asm. */
} else {
/* Handle error here. */
}
string *one_big_string;
one_big_string->the_string = malloc(sizeof(char)); // Aside: You can leave out sizeof(char). It is defined by the standard to be 1
one_big_string->length = 0;
此处的内容不确定。它没有指出任何有意义的事情。您需要先为 分配空间,然后为其成员分配内存。也有类似的问题。one_big_string
one_big_string
new_string
然后,您需要按照分配此内存的相反顺序进行此内存。free()
评论
sizeof(argv[1]
是指针的大小,而不是参数的长度,您可能想要。 和两个未初始化的指针。您需要使用字符串 *new_string = malloc(sizeof(string));' 完成后,您也需要释放它们。strlen
string *one_big_string;
string *new_string;
malloc. Like
string *one_big_string; one_big_string->the_string = malloc(sizeof(char));
是未定义的行为。该变量未初始化,因此尝试引用是错误的。在获得有效值之前,无法分配。one_big_string
one_big_string->the_string
one_big_string->the_string
one_big_string