- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 strtok_r()
实现遇到问题。我正在解析一个文本文件,如果遇到 ";"
,它会将其视为注释并忽略它,解析文件中的标记(由空格分隔的任何内容)。
这是一个这样的文件:
1) ;;
2) ;; Basic
3) ;;
4)
5) defun main
6) 5 3 2 * + printnum endl ;; (3 * 2) + 5 = 11
7) 3 4 5 rot * + printnum endl ;; (3 * 5) + 4 = 19
8) return
我正在做的是,一旦我 fgets()
一行,我就会使用 strtok_r()
解析该行。这是尝试此操作的完整函数:
void read_token(token* theToken, char* j_file, char* asm_file)
{
//Declare and initialize variables
int len;
char line[1000];
char *semi_token = NULL;
char* parse_tok = NULL;
char* assign = NULL;
//Open file to begin parsing
FILE *IN = fopen(j_file, "r");
//If file pointer NULL
if (IN == NULL)
{
//Print error message
printf("error: file does not exist\n");
//Terminate program
exit(1);
}
//File pointer not NULL
else
{
//Initialize char_token linked list
parsed_element* head = init_list_head();
head->token = "start";
print_list(head);
//Get characters from .j FILE
while (!feof(IN))
{
//Get each line of .j file
fgets(line, 1000, IN);
//Compute length of each line
len = strlen(line);
//If length is zero or if there is newline escape sequnce
if (len > 0 && line[len-1] == '\n')
{
//Replace with null
line[len-1] = '\0';
}
//Search for semicolons in .J FILE
semi_token = strpbrk(line, ";\r\n\t");
//Replace with null terminator
if (semi_token)
{
*semi_token = '\0';
}
// printf("line is %s\n",line );
//Copy each line
assign = line;
// printf("line is %s\n",line );
len = strlen(line);
printf("line length is %d\n",len );
// parse_tok = strtok(line, "\r ");
//Parse each token in line
while((parse_tok = strtok_r(assign, " ", &assign)))
{
printf("token is %s\n", parse_tok);
insert_head(&head, parse_tok);
print_list(head);
//Obtain lentgh of token
// len = strlen(parse_tok);
// printf("len is %d \n", len);
}
}
}
}
我正在将每个标记加载到一个单链表中。这是构成列表中每个节点的结构:
typedef struct parsed_element
{
char* token;
struct parsed_element* next;
} parsed_element;
各方面按预期工作
1) 在删除所有 ";"
和空格分隔符后,我的函数正确地分隔了 fgets() 中的每一行。以下是作为证明的输出:
1) line length is 0
2) line length is 0
3) line length is 0
4) line length is 0
5) line length is 10
6) line length is 23
7) line length is 27
8) line length is 6
2)我的函数正确地标记了每一行。以下是确认这一点的输出:
token is defun
token is main
token is 5
token is 3
token is 2
token is *
token is +
token is printnum
token is endl
token is 3
token is 4
token is 5
token is rot
token is *
token is +
token is printnum
token is endl
token is return
方面未按预期工作
1)当我尝试将每个标记插入单链表时,问题就出现了。获得每个标记后,我将标记传递到一个函数中,该函数将其插入到已初始化的链表的头部。包含 strtok_r()
的 while 循环中每次迭代后的预期行为为:
1) List is: Start
2) List is defun Start
3) List is main defun Start
4) List is: 5 main defun Start
5) List is: 3 5 main defun Start
6) List is: 2 3 5 main defun Start
7) List is: * 2 3 5 main defun Start
8) List is: + * 2 3 5 main defun Start
9) List is: printnum + * 2 3 5 main defun Start
10) List is: endl printnum + * 2 3 5 main defun Start
11) List is: 3 endl printnum + * 2 3 5 main defun Start
12) List is: 4 3 endl printnum + * 2 3 5 main defun Start
13) List is: 5 4 3 endl printnum + * 2 3 5 main defun Start
14) List is: rot 5 4 3 endl printnum + * 2 3 5 main defun Start
14) List is: * rot 5 4 3 endl printnum + * 2 3 5 main defun Start
16) List is: + * rot 5 4 3 endl printnum + * 2 3 5 main defun Start
17) List is: printnum + * rot 5 4 3 endl printnum + * 2 3 5 main defun Start
18) List is: endl printnum + * rot 5 4 3 endl printnum + * 2 3 5 main defun Start
19) List is: return endl printnum + * rot 5 4 3 endl printnum + * 2 3 5 main defun Start
相反,这是我观察到的:
1) List is: start
2) List is: defun start
3) List is: main defun start
4) List is: 5 * + printnum endl 5 start
5) List is: 3 5 * + printnum endl 5 start
6) List is: 2 3 5 * + printnum endl 5 start
7) List is: * 2 3 5 * 5 start
8) List is: + * 2 3 5 * 5 start
9) List is: printnum + * 2 3 5 * 5 start
10) List is: endl printnum + * 2 3 5 * 5 start
11) List is: 3 num endl * + printnum endl t * + printnum endl rot * + printnum endl 5 rot * + printnum endl 4 5 rot * + printnum endl 3 rot * + printnum endl 3 start
12) List is: 4 3 num endl * + printnum endl t * + printnum endl rot * + printnum endl 5 rot * + printnum endl 4 3 rot * + printnum endl 3 start
13) List is: 5 4 3 num endl * + printnum endl t * + printnum endl rot * + printnum endl 5 4 3 rot * + printnum endl 3 start
14) List is: rot 5 4 3 num endl * + printnum endl t rot 5 4 3 rot 3 start
15) List is: * rot 5 4 3 num endl * t rot 5 4 3 rot 3 start
16) List is: + * rot 5 4 3 num endl * t rot 5 4 3 rot 3 start
17) List is: printnum + * rot 5 4 3 num * t rot 5 4 3 rot 3 start
18) List is: endl printnum + * rot 5 4 3 num * t rot 5 4 3 rot 3 start
19) List is: return endl printnum + * rn turn return num * t rn turn return return start
第三次迭代后,我的插入头函数失败,并且没有在列表的头部插入每个标记。事实上,它在某种程度上破坏了我的代币。为什么会发生这种情况呢?我很确定这不是我的链表 insert_head()
和 print_list()
函数的实现。
这些已经过严格测试并证明适用于其他应用程序。我的感觉是,这与我解析每个标记的方式有关?或者这些实用程序交互的方式?
我发布了 insert_head()
print_list()
函数的代码以供引用:
LIST_STATUS insert_head(struct parsed_element** head, char* token);
void print_list(struct parsed_element* head);
LIST_STATUS insert_head(struct parsed_element** head, char* token)
{
//Check if parsed_element** head returns NULL
if (!*head)
{
//Return status
return LIST_HEAD_NULL;
}
//Case where head is not NULL
else
{
//Create new node
parsed_element* new_node;
//Malloc space for new node
new_node = (parsed_element*)malloc(sizeof(parsed_element));
//Case where malloc returns void*
if (new_node != NULL)
{
//Set tokenue of new node
new_node->token = token;
//Point new node to address of head
new_node->next = *head;
//New node is now head node (CHECK FOR POTENTIAL ERRORS)
*head = new_node;
//Return status
return LIST_OKAY;
}
//Case where malloc returns NULL
else
{
//Print malloc error
printf("Malloc error: aborting\n");
exit(0);
}
}
}
void print_list(struct parsed_element* head)
{
//Create variable to store head pointer
parsed_element* print_node = head;
//Print statement
printf("List is: ");
//Traverse list
while (print_node != NULL)
{
//Print list element
printf("%s ",print_node->token);
//Increment pointer
print_node = print_node->next;
}
//Print newline
printf("\n");
}
最佳答案
您的函数read_token
使用局部变量line
来读取文件内容。当使用 strtok
标记此行时,您将收到指向为该局部变量分配的内存的指针。然后将此类指针传递给另一个函数 insert_head
,该函数只是分配指针(但不复制内容),一旦 read_token<,将导致列表节点指向“无效”内存
已结束(当超出范围时,即当 read_token
结束时,line
将变得无效)。
所以而不是
new_node->token = token;
您需要复制 token 的内容,即写入
new_node->token = malloc(strlen(token)+1);
strcpy(new_node->token,token);
关于c - strtok_r 的行为不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51012269/
我们如何让 SwiftUI 对象,尤其是 Image,符合 Hashable 协议(protocol)? 我知道它们符合 Equatable 协议(protocol),所以主要问题是如何获取哈希值,或
我遇到了一些符合 AVAudioPlayerDelegate 的奇怪问题。以下正是我在一个全新的 Xcode 项目中所拥有的: import UIKit import AVFoundation cla
我一辈子都弄不明白为什么我会收到此类不符合 NSCoding 协议(protocol)的错误。也许另一双眼睛会有所帮助。我试图添加注释以明确每个函数在做什么。 import Foundation im
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
所有现代浏览器都理解 HTML,所以除了在键盘最右侧编写更多字符之外,兼容 XHTML 的意义何在。 最佳答案 没有一点我能想到的。 W3C 已经取消了 XHTML 2.0,尽管应该有一个 XHTML
我正在设计一个订单系统,状态设计模式似乎很合适,因为订单可以更改其状态,从而更改订单允许的功能。下面是我的基本类图: 我不喜欢这种方法,因为客户端无法查看某个方法是否受支持并且违反了里氏原则。我在下面
我正在考虑使用图形数据库来存储 IFC数据。理想情况下,数据库应该提供一种方法来定义 IFC 架构中定义的所有规则类型。但是,我不认为有任何这样的数据库,因为 IFC 中的某些规则类型非常复杂并且需要
我所在的组织必须满足 FISMA 对启用 FIPS 的系统的要求。我正在尝试做的一件事是为我们的密码实现哈希算法。我对此有很多选择:SHA-2、MD5、bcrypt(使用 Blowfish)、RIPE
我正在尝试实现我的自定义 CoreData Carpark 实体以符合 MKAnnotation,就像我们如何使 class 对象符合 >MKAnnotation. 我根据以下帖子调整了我的实现:th
我在 project-Swift.h 文件中收到名为“CBCentralManagerDelegate”的 No 类型或协议(protocol)。不知道我在这里哪里出错了。我认为这与 swift.h
我正在尝试读取之前写入 NVM 闪存的变量的值。 我的代码是: uintptr_t address = getAddress(); //[MISRA C++ Rule 5-2-8] cast from
所以我有这个练习要解决。我必须创建第一个。一个名为 Printable 的接口(interface),它有一个 put() 方法,该方法将接受实现 Comparable 的对象。 完成 interfa
我的问题涉及 IEEE 754 单精度数字。假设我有一个结构: typedef struct __ieee754 { int sign; int exponent; int mant
我需要使用 map,键为 uint32_t,值为 Meshes。我希望将网格布局在连续的内存中以 boost 性能,因为它们将经常被连续访问。 我想知道有哪些内存分配器库可以提供以下内容; 分配给连续
在处理小对象时,有哪些分配器可用于 STL。我已经尝试过使用 Boost 的池分配器,但没有得到任何性能提升(实际上,在某些情况下性能下降相当大)。 最佳答案 你没有说你使用的是什么编译器,但它可能带
我想做什么 我有一种划分事物的方法。此方法不会对数组进行完全排序;它只是简单地对数组进行分区,以便一侧的所有元素(某些预先确定的“中心”或“中点值”——但它不必导致均匀拆分)小于“中心”和另一侧的所有
假设我需要开发一个 REST 银行应用程序允许创建/销毁银行账户以及对帐户进行以下操作:withdraw/credit/getBalance。 创建帐户 PUT/银行/约翰 这里我使用 PUT 而不是
假设我有一个 struct 符合我的模型的 Equatable,如下所示: struct Model: Equatable { var a: Int = 0 var b: String
我目前正在研究 Decodable、Encodable 和 friend ,试图理解它背后的“魔法”。 以下是我发现不寻常的一件事: class Person: Decodable { var n
在 Swift 书中,枚举的例子很好用 enum CompassPoint: String { case north, south, east, west } var northCom = C
我是一名优秀的程序员,十分优秀!