Untitled

 avatar
unknown
c_cpp
3 months ago
2.0 kB
2
Indexable
#include <stdio.h>
#include <string.h>

// 测试函数
// 模拟从serial缓冲区中拷贝数据的过程
int read(char* dst, int max)
{
	static int _run = -1;
	_run += 1;
	
	switch(_run)
	{
		case 0:{
			const char Data[] = "1,23,4";
			memcpy(dst, Data, sizeof(Data)-1);
			
			return sizeof(Data)-1;
		}
		case 1:{
			const char Data[] = ",5,6,7,100,";
			memcpy(dst, Data, sizeof(Data)-1);
			
			return sizeof(Data)-1;
		}
		case 2:{
			const char Data[] = "1,2,";
			memcpy(dst, Data, sizeof(Data)-1);
			
			return sizeof(Data)-1;
		}
		default: return 0;
	}
}

int main()
{
	// 测试sscanf特性
    if (false)
    {
        int num, pos;
        char space[2];
        int ret = sscanf("12,,", "%d%1[,]%n", &num, space, &pos);
        printf("ret:%d, pos:%d", ret, pos);
        return 0;
    }
    
	char buf[20]{};
	char* end = buf;
	int len = 0;

	while(len = read(end, sizeof(buf)-(end-buf)), len > 0)
	{
		// 更新end
		end += len;
		*end = '\0';
		
		// 尝试吃掉输入流中的 \d+,
		// 并使用未处理数据向前覆盖已处理数据
		
		int num, pos; // pos代表已处理的数据
		char space[2]; // 强制捕获1个字节宽的分割符号, 否则无法判断sscanf是否完整的捕获了表达式
		while (sscanf(buf, "%d%1[,]%n", &num, space, &pos) == 2)
		{
			// 对捕获的数字进行处理
			// ...
			printf("get %d\n", num);
			
			// 缓冲区中的数据总数
		    int total_len = end - buf;
			
			// 计算未处理的数据长
			int unused_len = total_len - pos;
			
			// 使用未处理数据覆盖已处理数据
			memmove(buf, buf+pos, unused_len);
			
			// 更新end
			end = buf + unused_len;
			*end = '\0';
		}
		
		// 10ms的接收时间, 或是更换为协程的wait
		// 在这段时间内等待串口缓冲区被另一线程的task填充
		// 否则表示流传输停止, 跳出循环
		// delay(10);
	}
	
	return 1;
}
Editor is loading...
Leave a Comment