求救啊,快脑子炸了,字符串的问题。。。。

sundaygeek 2012-08-28 03:21:10
艹啊,网速能不能给力点,发这个就发了三遍了。。。

我的任务是解析一段客户机发来的字符串,这段字符串包含了一个或者多个信息段,信息段之间用分号隔开,每个信息段有下面的几个字段,字段之间用逗号隔开,怎么解析这段字符串(注意是字符串),解析成下面的结构体形式。

struct recived_st
{
unsigned char client_id[40];
unsigned int client_ip;
unsigned short client_port;
unsigned int tunnel_ip;
unsigned short tunnel_port;
unsigned int app_ip;
unsigned short app_port;
long time;
unsigned short index_port;
};


————————————————————
...全文
398 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
WizardOz 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 4 楼 的回复:

那就先用strtok找";".
或者用strchr()自己查找位置。然后解析。

其实很少用字符串传数据的……


谁知道主管怎么想的,脑子坏了。。。
[/Quote]
用可见字符传递的话,调试和测试都很方便的。。。
你可以用其它发送工具,自己编辑消息发送给服务器,这样在测试阶段不是很方便吗?

你这个方法很多啊,就像前面说的sscanf,个人推荐正则式,还可以对输入的数据做一些限制。
sundaygeek 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]

既然是项目上的东西, 就要考虑稳定和安全性, 不要用特定的函数, 还自己写个函数 来解析 以逗号为分隔符的字符串
[/Quote]

嗯,主管也是这样说的,不让用strtok.....让自己写一个函数,我是个菜鸟啊,刚来一个月,我去啊,这一段时间被数组和指针弄得头都大了。

我本科是学电子,现在研究生是学通信的,但是导师是研究前沿通信理论的,有点不太实用,师兄师姐有做java的,有做c#的,也有跟着导师做通信算法的。
我也开学就研二了。不知道自己干什么。亚历山大啊。。。
本科单片机也学了一点,现在arm、fpga也接触了一点,在公司实习只能用C的网络,C++、python也学了一点,究竟干什么都产生了怀疑,不知道自己能做什么,但是旁边的同学都说我挺牛逼的,但是我没有发现自己的牛逼点,想请教各位大侠,各位过来人,我该怎么办。现在看见代码就头大。。。。

各位,求救给指点迷津啊。。。。
无影树下 2012-08-28
  • 打赏
  • 举报
回复
既然是项目上的东西, 就要考虑稳定和安全性, 不要用特定的函数, 还自己写个函数 来解析 以逗号为分隔符的字符串
mujiok2003 2012-08-28
  • 打赏
  • 举报
回复
确保发送端和接收端的读写方式一致,没有大小端等问题。


struct recived_st
{
unsigned char client_id[40];
unsigned int client_ip;
unsigned short client_port;
unsigned int tunnel_ip;
unsigned short tunnel_port;
unsigned int app_ip;
unsigned short app_port;
long time;
unsigned short index_port;
};


char* recv_buf;
std::istringsteam iss(recv_buf);
recived_st theST;
std::string clientID;
char sep;
iss.getline(clientID, ',');
strcpy(theST.client_id, clientID.c_str());
iss >> theST.client_ip >> sep
>> theST.client_port >> sep
>> theST.tunnel_ip >> sep
>> theST.tunnel_port >> sep
>> theST.app_ip >> sep
>> theST.app_port >> sep
>> theST.time >> sep
dic_008 2012-08-28
  • 打赏
  • 举报
回复
MSDN上的例子,截取出来,进行类型转换就行了,给结构体相应位置赋值就行了。脑子都炸了

#include <string.h>
#include <stdio.h>

char string[] = "A string\tof ,,tokens\nand some more tokens";
char seps[] = " ,\t\n";
char *token;

void main( void )
{
printf( "%s\n\nTokens:\n", string );
/* Establish string and get the first token: */
token = strtok( string, seps );
while( token != NULL )
{
/* While there are tokens in "string" */
printf( " %s\n", token );
/* Get next token: */
token = strtok( NULL, seps );
}
}


兆帅 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

C/C++ code

struct recived_st
{
unsigned char client_id[40];
unsigned int client_ip;
unsigned short client_port;
unsigned int tunnel_ip;
unsigned short tunnel_port;
unsigned ……
[/Quote]
学习了。。
misshare 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

三步:
1、解析码流,以;为标记取出信息段;
2、解析信息段,以,为标记取出字段码流;
3、分析各字段的合法性,并翻译之后,填入结构体变量。
[/Quote]
+1
赵4老师 2012-08-28
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
#include <string.h>
char string[80];
char seps1[3];
char seps2[3];
char *token;
char *zzstrtok (
char *string,
const char *control1,//连续出现时视为中间夹空token
const char *control2 //连续出现时视为中间无空token
)
{
unsigned char *str;
const unsigned char *ctrl1 = control1;
const unsigned char *ctrl2 = control2;
unsigned char map1[32],map2[32];
static char *nextoken;
static char flag=0;
unsigned char c;
int L;

memset(map1,0,32);
memset(map2,0,32);
do {
map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));
} while (*ctrl1++);
do {
map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));
} while (*ctrl2++);

if (string) {
if (control2[0]) {
L=strlen(string);
while (1) {
c=string[L-1];
if (map2[c >> 3] & (1 << (c & 7))) {
L--;
string[L]=0;
} else break;
}
}
if (control1[0]) {
L=strlen(string);
c=string[L-1];
if (map1[c >> 3] & (1 << (c & 7))) {
string[L]=control1[0];
string[L+1]=0;
}
}
str=string;
}
else str=nextoken;

string=str;
while (1) {
if (0==flag) {
if (!*str) break;
if (map1[*str >> 3] & (1 << (*str & 7))) {
*str=0;
str++;
break;
} else if (map2[*str >> 3] & (1 << (*str & 7))) {
string++;
str++;
} else {
flag=1;
str++;
}
} else if (1==flag) {
if (!*str) break;
if (map1[*str >> 3] & (1 << (*str & 7))) {
*str=0;
str++;
flag=0;
break;
} else if (map2[*str >> 3] & (1 << (*str & 7))) {
*str=0;
str++;
flag=2;
break;
} else str++;
} else {//2==flag
if (!*str) return NULL;
if (map1[*str >> 3] & (1 << (*str & 7))) {
str++;
string=str;
flag=0;
} else if (map2[*str >> 3] & (1 << (*str & 7))) {
str++;
string=str;
} else {
string=str;
str++;
flag=1;
}
}
}
nextoken=str;

if (string==str) return NULL;
else return string;
}
void main()
{
strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some more tokens, ");
strcpy(seps1,",\n");strcpy(seps2," \t");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");
strcpy(seps1,"|");strcpy(seps2," ");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"1234|LIYI||010|201110260000|OK");
strcpy(seps1,"");strcpy(seps2,"|");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"1234|LIYI||010|201110260000|OK");
strcpy(seps1,"|");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"a");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"a,b");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"a,,b");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",a");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,"a,");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",a,,b");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",,a,,b,,");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",,");
strcpy(seps1,",");strcpy(seps2,"");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}

strcpy(string,",,,");
strcpy(seps1,",");strcpy(seps2," ");
printf("\n[%s]\nTokens:\n",string);
token=zzstrtok(string,seps1,seps2);
while (token!=NULL) {
printf(" <%s>",token);
token=zzstrtok(NULL,seps1,seps2);
}
}
//
//[A string of ,,tokens
//
//and some more tokens,]
//Tokens:
// <A>, <string>, <of>, <>, <tokens>, <>, <and>, <some>, <more>, <tokens>, <>,
//[1234| LIYI|China | 010 |201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <China>, <010>, <201110260000>, <OK>,
//[1234|LIYI||010|201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <010>, <201110260000>, <OK>,
//[1234|LIYI||010|201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <>, <010>, <201110260000>, <OK>,
//[a]
//Tokens:
// <a>,
//[a,b]
//Tokens:
// <a>, <b>,
//[a,,b]
//Tokens:
// <a>, <>, <b>,
//[,a]
//Tokens:
// <>, <a>,
//[a,]
//Tokens:
// <a>, <>,
//[,a,,b]
//Tokens:
// <>, <a>, <>, <b>,
//[,,a,,b,,]
//Tokens:
// <>, <>, <a>, <>, <b>, <>, <>,
//[,]
//Tokens:
// <>, <>,
//[,,]
//Tokens:
// <>, <>, <>,
//[,,,]
//Tokens:
// <>, <>, <>, <>,
lin5161678 2012-08-28
  • 打赏
  • 举报
回复

sprintf
很方便
sscanf
更方便
www_adintr_com 2012-08-28
  • 打赏
  • 举报
回复

struct recived_st
{
unsigned char client_id[40];
unsigned int client_ip;
unsigned short client_port;
unsigned int tunnel_ip;
unsigned short tunnel_port;
unsigned int app_ip;
unsigned short app_port;
long time;
unsigned short index_port;
};

int main(void)
{
char input[] = "abc,111,222,555,333,444,78,1000,100";
char* p = input;
recived_st s;

while(*p != '\0')
{
*p = (*p == ',') ? ' ' : *p;
++p;
}

sscanf(input, "%s %d %hd %d %hd %d %hd %ld %hd", s.client_id, &s.client_ip, &s.client_port,
&s.tunnel_ip, &s.tunnel_port, &s.app_ip, &s.app_port, &s.time, &s.index_port);

return 0;
}
sundaygeek 2012-08-28
  • 打赏
  • 举报
回复

#include <string.h>
#include <stdio.h>

char* abc(char* input,char* sep);

int main(void)
{
char input[30] = "abc,111,222;bbb,333,444";
char aa[5][5];
char *p;
int i=0,n=0,j=0;
p = strtok(input, ";");
if(p){n++;strcpy(aa[i++],p);printf("%s\n", p);}
while(1)
{
p = strtok(NULL, ";");
if(p){n++;strcpy(aa[i++],p);printf("%s\n",p);}
else{break;}
}

for(int j=0;j<n;j++)
{
printf("%s\n",aa[j]);
}
return 0;
}


aa数组怎么显示不对呢。
接下来不知道怎么解析了。还要把每一个aa解析一遍。。。?!!!!
allenbein 2012-08-28
  • 打赏
  • 举报
回复
三步:
1、解析码流,以;为标记取出信息段;
2、解析信息段,以,为标记取出字段码流;
3、分析各字段的合法性,并翻译之后,填入结构体变量。
Proteas 2012-08-28
  • 打赏
  • 举报
回复
那就先用strtok找";".
或者用strchr()自己查找位置。然后解析。

其实很少用字符串传数据的,都是用二进制流传,性能高很多。
如果要用字符串,还不如用json。让json来解析数据。
要不就用protobuf。
=======================================================
这样比较合理。
如果没有办法改成这样的方法。
那就递归下降的方法来解析,
每次读取一个“;”的数据,
然后再解析这段数据。
sundaygeek 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

那就先用strtok找";".
或者用strchr()自己查找位置。然后解析。

其实很少用字符串传数据的……
[/Quote]

谁知道主管怎么想的,脑子坏了。。。
ies_sweet 2012-08-28
  • 打赏
  • 举报
回复
客户端是谁做的?
能改设计吗?
真心的,用二进制流来传输数据更好!
因为这是机器之间的交流
不牵扯到人的交流
图灵狗 2012-08-28
  • 打赏
  • 举报
回复
用sscanf类似这样"%s,%d,%d,%d,%d,%d,%d,%l,%d"的格式。
冻结 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

引用 2 楼 的回复:

C语言的话就用strtok按照","解析字符串。
解析出字符串后再使用strcpy(), atoi(), atol()函数为结构体对象赋值。

两个帖子,就两个回复。


但是消息之间是用分号间隔的啊。
[/Quote]
那就先用strtok找";".
或者用strchr()自己查找位置。然后解析。

其实很少用字符串传数据的,都是用二进制流传,性能高很多。
如果要用字符串,还不如用json。让json来解析数据。
要不就用protobuf。
sundaygeek 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

C语言的话就用strtok按照","解析字符串。
解析出字符串后再使用strcpy(), atoi(), atol()函数为结构体对象赋值。

两个帖子,就两个回复。
[/Quote]

但是消息之间是用分号间隔的啊。
冻结 2012-08-28
  • 打赏
  • 举报
回复
C语言的话就用strtok按照","解析字符串。
解析出字符串后再使用strcpy(), atoi(), atol()函数为结构体对象赋值。

两个帖子,就两个回复。
sundaygeek 2012-08-28
  • 打赏
  • 举报
回复
沙发我先占着,在线等啊。。。。。。。。。。。。

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧