C Printf in循环在没有初始print语句的情况下不工作
我正在尝试用C编写一个非常基本的lexer,并拥有以下代码,该代码应该只执行以下操作: 输入:C Printf in循环在没有初始print语句的情况下不工作,c,C,我正在尝试用C编写一个非常基本的lexer,并拥有以下代码,该代码应该只执行以下操作: 输入:“12 142 123” 输出: NUMBER -- 12 NUMBER -- 14 NUMBER -- 123 但是,我遇到了一个问题,如果在循环输入之前没有包含初始的printf(“”语句,那么我将得到如下输出: 输出: 其中第一个数字为空。我真的很困惑,为什么会发生这种情况,我真的很感谢一些帮助 我有以下代码(省略了一些不相关的函数) 在number中,arr是一个局部变量。局部变量在其函数结束
“12 142 123”
输出:
NUMBER -- 12
NUMBER -- 14
NUMBER -- 123
但是,我遇到了一个问题,如果在循环输入之前没有包含初始的printf(“”
语句,那么我将得到如下输出:
输出:
其中第一个数字为空。我真的很困惑,为什么会发生这种情况,我真的很感谢一些帮助
我有以下代码(省略了一些不相关的函数)
在
number
中,arr
是一个局部变量。局部变量在其函数结束时被销毁,其内容不可预测。尽管如此,您的程序还是使用标记中的指针打印其值
打印的值不可预测。额外的printf(“”)
语句可能会导致编译器重新排列代码,使变量不会被覆盖,或者类似的情况。你不能依赖它
您还有几个其他选项可以为每个令牌分配内存:
- 在
token
中更改str
,使其成为字符数组而不是指针。然后每个令牌都有自己的空间来存储字符串
- 使用
malloc
分配字符串。然后它会一直保持分配状态,直到您释放它
- 在
main
中创建数组,使其对next
和print\u-tok
都有效。您必须给next
一个指向数组的指针,以便它知道应该将字符串存储在哪里。这将一次只存储一个令牌的字符串
- 基本上,除了在
next
中将数组作为局部变量之外,还可以使用任何其他方法创建数组
- 使指针指向标记在原始字符串中的位置。在
Token
中添加另一个变量,用于存储令牌的长度
我认为第一个选项最简单,最后一个选项使用的内存最少,但为了完整性,我还包括了一些其他选项。在number
中,arr
是一个局部变量。局部变量在其函数结束时被销毁,其内容不可预测。尽管如此,您的程序还是使用标记中的指针打印其值
打印的值不可预测。额外的printf(“”)
语句可能会导致编译器重新排列代码,使变量不会被覆盖,或者类似的情况。你不能依赖它
您还有几个其他选项可以为每个令牌分配内存:
- 在
token
中更改str
,使其成为字符数组而不是指针。然后每个令牌都有自己的空间来存储字符串
- 使用
malloc
分配字符串。然后它会一直保持分配状态,直到您释放它
- 在
main
中创建数组,使其对next
和print\u-tok
都有效。您必须给next
一个指向数组的指针,以便它知道应该将字符串存储在哪里。这将一次只存储一个令牌的字符串
- 基本上,除了在
next
中将数组作为局部变量之外,还可以使用任何其他方法创建数组
- 使指针指向标记在原始字符串中的位置。在
Token
中添加另一个变量,用于存储令牌的长度
我认为第一个选项最简单,最后一个选项使用的内存最少,但为了完整性,我还包括了一些其他选项。Token ret={NUMBER,(char*)arr}代码>您正在使用指向局部变量的指针。您需要malloc
string+term的空格并进行复制。您描述的内容到处都是未定义的行为。Token ret={NUMBER,(char*)arr}代码>您正在使用指向局部变量的指针。您需要malloc
string+term的空格并进行复制。您描述的内容都有未定义的行为。谢谢,这很有意义。解决方案是为结构分配非本地内存,然后返回指针吗?或者在这种情况下还有其他首选方法吗?@mlz7您可以:(1)“malloc”字符数组(并将其释放到其他地方),(2)在main中局部声明arry(或作为全局变量…),并将其作为参数传递给number
,(3)也许最快的解决方案就是使用static
存储在number
中,这样阵列的生命周期就是整个生命周期中的一个program@mlz7第一种解决方案更“通用”,因为它也适用于多线程环境。无论如何,如果您的应用程序是单线程的,那么解决方案2和解决方案3可以成为第三个最快的解决方案。@mlz7不客气。Ps:这个答案会很好,如果它还包含一些关于如何解决问题的建议(代码部分似乎与OP的代码完全相同),那么它将获得我的UV。如果你愿意,你可以修改我的评论。谢谢,这很有意义。解决方案是为结构分配非本地内存,然后返回指针吗?或者在这种情况下还有其他首选方法吗?@mlz7您可以:(1)“malloc”字符数组(并将其释放到其他地方),(2)在main中局部声明arry(或作为全局变量…),并将其作为参数传递给number
,(3)也许最快的解决方案就是使用static
存储在number
中,这样阵列的生命周期就是整个生命周期中的一个program@mlz7第一种解决方案更“通用”,因为它也适用于多线程环境。无论如何,如果您的应用程序是单线程的,那么解决方案2和解决方案3可以成为第三个最快的解决方案。@mlz7不客气。附言:这个答案会很好,如果它也包含一些糖,我的紫外线会增加
NUMBER --
NUMBER -- 14
NUMBER -- 123
#define MAX_LEN 400
char* input;
char* ptr;
char curr_type;
char curr;
enum token_type {
END,
NUMBER,
UNEXPECTED
};
typedef struct {
enum token_type type;
char* str;
} Token;
void print_tok(Token t) {
printf("%s -- %s\n", token_types[t.type], t.str);
}
char get(void) {
return *ptr++;
}
char peek(void) {
return *ptr;
}
Token number(void) {
char arr[MAX_LEN];
arr[0] = peek();
get();
int i = 1;
while (is_digit(peek())) {
arr[i] = get();
++i;
}
arr[++i] = '\0';
Token ret = {NUMBER, (char*)arr};
return ret;
}
Token unexpected(void) {
// omitted
}
Token next(void) {
while (is_space(peek())) get();
char c = peek();
switch (peek()) {
case '0':
// omitted
case '9':
return number();
default:
return unexpected();
}
}
int main(int argc, char **argv) {
printf(""); // works fine with this line
input = argv[1];
ptr = input;
Token tokens[MAX_LEN];
Token t;
int i = 0;
do {
t = next();
print_tok(t);
tokens[i++] = t;
} while (t.type != END && t.type != UNEXPECTED);
return 0;
}