习题1:
#include <stdio.h>
#include <string.h>
static char *pp;
static size_t len;
char *strtok2(char *str, const char *delim)
{
char *pos;
if (str != NULL) {
len = strlen(delim);
pp = str;
}
str = pp;
if (str == NULL) return NULL;
pos = strstr(str, delim);
if (pos != NULL) {
*pos = '\0';
pp = pos + len;
} else {
pp = NULL;
}
return str;
}
char *strtok_r2(char *str, const char *delim, char **saveptr)
{
char *pos;
int len = strlen(delim);
if (str == NULL) {
str = *saveptr;
}
if (str == NULL) return NULL;
pos = strstr(str, delim);
if (pos != NULL) {
*pos = '\0';
*saveptr = pos + len;
} else {
*saveptr = NULL;
}
return str;
}
int main(void)
{
char str[] = "root:x::0:root:/root:/bin/bash:";
char *token;
token = strtok2(str, ":");
printf("%s\n", token);
while ((token = strtok2(NULL, ":")) != NULL)
printf("%s\n", token);
printf("============\n");
char str2[] = "root=x=:0:root=/root:=bin/bash:";
char *save_ptr;
token = strtok_r2(str2, "=", &save_ptr);
printf("%s\n", token);
while ((token = strtok_r2(NULL, "=", &save_ptr)) != NULL)
printf("%s\n", token);
return 0;
}习题2:
har *)malloc(MAX_LEN);
char *pos = strchr(url, '?');
u.pnum = 0;
if (pos != NULL) {
strncat(u.url_path, url, pos - url);
char *token;
token = strtok(pos + 1, "&");
set_param(&u.plist[u.pnum++], token);
while ((token = strtok(NULL, "&")) != NULL) {
set_param(&u.plist[u.pnum++], token);
}
} else {
strcat(u.url_path, url);
}
return u;
}
void free_url(url_t u) {
free(u.url_path);
u.url_path = NULL;
int i;
for (i = 0; i < u.pnum; i++) {
free(u.plist[i].q);
u.plist[i].q = NULL;
free(u.plist[i].v);
u.plist[i].v = NULL;
}
}
void print_url(url_t u) {
printf("path: %s\n", u.url_path);
int i;
for (i = 0; i < u.pnum; i++) {
printf("==========\n");
printf("q: %s\n", u.plist[i].q);
printf("v: %s\n", u.plist[i].v);
}
}
int main(void)
{
//char *url;//this is the problem
char url[MAX_LEN];
scanf("%s", url);
url_t u = parse_url(url);
print_url(u);
free_url(u);
}重发第2题:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 10 //max param numbers
#define MAX_LEN 100 // max len of path
#define MAX_P 20 // max len of param
struct param_t {
char *q;
char *v;
};
typedef struct {
char *url_path;
struct param_t plist[N];
int pnum;
} url_t;
void set_param(struct param_t *p, char *token) {
char *pos = strchr(token, '=');
p->q = (char *)malloc(MAX_P);
p->v = (char *)malloc(MAX_P);
if (pos != NULL) {
p->q = strncat(p->q, token, pos - token);
p->v = strcat(p->v, pos + 1);
} else {
p->q = strcat(p->q, token);
*(p->v) = '\0';
}
}
url_t parse_url(char *url)
{
char header[8] = "http://";
char url_header[8];
strncpy(url_header, url, 7);
url_header[7] = '\0';
header[7] = '\0';
if (strcmp(url_header, header)) {
printf("url error!\n");
exit(2);
}
url_t u;
u.url_path = (char *)malloc(MAX_LEN);
char *pos = strchr(url, '?');
u.pnum = 0;
if (pos != NULL) {
strncat(u.url_path, url, pos - url);
char *token;
token = strtok(pos + 1, "&");
set_param(&u.plist[u.pnum++], token);
while ((token = strtok(NULL, "&")) != NULL) {
set_param(&u.plist[u.pnum++], token);
}
} else {
strcat(u.url_path, url);
}
return u;
}
void free_url(url_t u) {
free(u.url_path);
u.url_path = NULL;
int i;
for (i = 0; i < u.pnum; i++) {
free(u.plist[i].q);
u.plist[i].q = NULL;
free(u.plist[i].v);
u.plist[i].v = NULL;
}
}
void print_url(url_t u) {
printf("path: %s\n", u.url_path);
int i;
for (i = 0; i < u.pnum; i++) {
printf("==========\n");
printf("q: %s\n", u.plist[i].q);
printf("v: %s\n", u.plist[i].v);
}
}
int main(void)
{
//char *url;//this is the problem
char url[MAX_LEN];
scanf("%s", url);
url_t u = parse_url(url);
print_url(u);
free_url(u);
}第一题:
char *strtok(char *SOURCE, const char *DELIMITERS)
{
static char * lloc = NULL;
int i;
SOURCE != NULL ? lloc=SOURCE : 0;
if(lloc[0] == '\0')
return NULL;
for(i=0; lloc[i]!='\0'; i++){
if(matchchr(lloc[i], DELIMITERS)){
if(matchchr(lloc[i+1], DELIMITERS)){
lloc[i] = '\0';
continue;
}else
break;
}
}
if(lloc[i] == '\0'){
lloc = lloc+i;
return lloc-i;
}else{
lloc[i] = '\0';
lloc = lloc+i+1;
return lloc-i-1;
}
}
char *strtok_r(char *SOURCE, const char *DELIMITERS,
char **LASTS)
{
int i;
SOURCE != NULL ? *LASTS=SOURCE : 0;
if(*LASTS[0] == '\0')
return NULL;
for(i=0; (*LASTS)[i]!='\0'; i++){
if(matchchr((*LASTS)[i], DELIMITERS)){
if( matchchr( (*LASTS)[i+1], DELIMITERS) ){
(*LASTS)[i] = '\0';
continue;
}else
break;
}
}
if((*LASTS)[i] == '\0'){
*LASTS = *LASTS+i;
return *LASTS-i;
}else{
(*LASTS)[i] = '\0';
*LASTS = *LASTS+i+1;
return *LASTS-i-1;
}
}
int matchchr(char chr, const char * chs)
{
for(; *chs != '\0'; chs++){
if(*chs == chr){
return 1;
}
}
return 0;
}压缩了一点代码:
char *strtok(char *SOURCE, const char *DELIMITERS)
{
static char * lloc = NULL;
int i;
SOURCE != NULL ? lloc=SOURCE : 0;
if(lloc[0] == '\0')
return NULL;
for(i=0; lloc[i]!='\0'; i++){
if(matchchr(lloc[i], DELIMITERS)){
if(matchchr(lloc[i+1], DELIMITERS)){
lloc[i] = '\0';
continue;
}else
break;
}
}
if(lloc[i] != '\0')
lloc[i++] = '\0';
lloc = lloc+i;
return lloc-i;
}
char *strtok_r(char *SOURCE, const char *DELIMITERS,
char **LASTS)
{
int i;
SOURCE != NULL ? *LASTS=SOURCE : 0;
if(*LASTS[0] == '\0')
return NULL;
for(i=0; (*LASTS)[i]!='\0'; i++){
if(matchchr((*LASTS)[i], DELIMITERS)){
if( matchchr( (*LASTS)[i+1], DELIMITERS) ){
(*LASTS)[i] = '\0';
continue;
}else
break;
}
}
if((*LASTS)[i] != '\0')
(*LASTS)[i++] = '\0';
*LASTS = *LASTS+i;
return *LASTS-i;
}
int matchchr(char chr, const char * chs)
{
for(; *chs != '\0'; chs++){
if(*chs == chr)
return 1;
}
return 0;
}第一题
char *strtok(char *str, const char *delim) {
static char *startp = NULL;
if (str == NULL) {
while ((*startp) != '\0' && (*startp) == *delim) {
startp++;
}
str = startp;
} else {
startp = str;
}
while ((*startp) != '\0' && (*startp) != *delim) {
startp++;
}
if ((*startp) == *delim) {
*startp = '\0';
startp++;
}
while((*startp)==*delim){
startp++;
}
if(*str=='\0'){
return NULL;
}
return str;
}
char *strtok_r_custom(char* str, const char* delim, char** saveptr){
int delimlen = strlen(delim);
char *strstart;
if(str == NULL){
strstart = *saveptr;
while(cmpequal(*saveptr, delim, delimlen)==0){
(*saveptr)++;
}
if(cmpequal(*saveptr, delim, delimlen)==1){
**saveptr = '\0';
(*saveptr)++;
}
while(cmpequal(*saveptr, delim, delimlen)==1){
(*saveptr)++;
}
}else{
strstart = str;
while(cmpequal(str, delim, delimlen)==0){
str++;
}
if(cmpequal(str, delim, delimlen)==1){
*str = '\0';
str++;
}
while(cmpequal(str, delim, delimlen)==1){
str++;
}
*saveptr = str;
}
if((*strstart) == '\0'){
return NULL;
}
return strstart;
}
int cmpequal(char* str, char* delim, int delimlen){
if(*str=='\0'){
return 2;
}
for(int i=0; i<delimlen; i++){
if(*str==delim[i]){
return 1;
}
}
return 0;
}
1.5比较字符串中的函数并不仅是遇到'\0'才结束,当比较出现不同的字符时,比较也会结束。
确实表达不严谨,在正式出版的书里会改过来,谢谢指出!
#define PATH_LEN_MAX 100
#define QUERY_PARAM_LEN_MAX 20
#define QUERY_PARAM_NUMBER_MAX 10
#define NO_QUERY 1
#define SUCCESS 0
#define PATH_FORM_ILLEGAL -1
#define KEY_VALUE_PAIR_ERROR -2
#define QUERY_FORM_ERROR -3
typedef struct{
char key[QUERY_PARAM_LEN_MAX];
char value[QUERY_PARAM_LEN_MAX];
}query_param;
typedef struct{
char url_path[PATH_LEN_MAX];
query_param query_param_list[QUERY_PARAM_NUMBER_MAX];
int query_param_number;
}url;
int parse_url(char *url_str, url *instance)
{
url url_n;
char *token, *subtoken;
char *ptr1,*ptr2,*ptr3;
int i;
token = strtok_r(url_str, "?", &ptr1);
if (NULL == strstr(token, "http://"))
return PATH_FORM_ILLEGAL;
else
strcpy(instance->url_path, token);
if (NULL == ptr1)
return NO_QUERY;
for (i=0; token=strtok_r(ptr1, "&", &ptr2); i++,ptr1=NULL) {
if (subtoken=strtok_r(token, "=", &ptr3)) {
if ('\0'==*ptr3)
return KEY_VALUE_PAIR_ERROR;
strcpy(instance->query_param_list[i].key, subtoken);
strcpy(instance->query_param_list[i].value, ptr3);
}
strtok_r(NULL, "=", &ptr3);
if (NULL!=ptr3)
return KEY_VALUE_PAIR_ERROR;
}
if (0 == i)
return QUERY_FORM_ERROR;
instance->query_param_number = i;
return SUCCESS;
}
void print_error(int n)
{
switch(n){
case 1: printf("The url has not query!\n");
break;
case 0: printf("Get url success!\n");
break;
case -1: printf("Path form is wrong!\n");
break;
case -2: printf("key form is wrong!\n");
break;
case -3: printf("Query form is wrong\n");
break;
default: printf("Unkonwn error!\n");
break;
}
}
void print_url(url *purl)
{
int i = 0;
if ('\0'==*(purl->url_path)){
printf("Path is empty!\n");
return;
}
printf("PATH:%s\n",purl->url_path);
if (0==purl->query_param_number){
printf("Query key is empty!\n");
return;
}
for (; i<purl->query_param_number; i++) {
printf("---------QUERY KEY %d--------\n",i+1);
printf("KEY:%s\n",purl->query_param_list[i].key);
printf("VALUE:%s\n",purl->query_param_list[i].value);
}
}
int main(int argc, char *argv[])
{
char *url_s = "http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta= ";
url url_n;
int ret;
memset((void *)&url_n, 0x00, sizeof(url));
print_url(&url_n);
ret = parse_url(url_s, &url_n);
print_error(ret);
print_url(&url_n);
return 0;
}
第一题答案:
#include <stdio.h>
#include <stdlib.h>
int isdelim(const char *mark,const char *delim)
{
while(*delim!='\0')
{
if(*mark==*delim)
return 1;
delim++;
}
return 0;
}
char *strtok(char *str, const char *delim)
{
static char *local_pointer=NULL;
char *delim_char,*return_pointer;
if(!delim)
return NULL;
if(str)
{
local_pointer=str;
}
if(!local_pointer)
return NULL;
return_pointer=local_pointer;
while(*local_pointer!='\0')
{
if(isdelim(local_pointer,delim))
{
*local_pointer='\0';
local_pointer++;
return return_pointer;
}
local_pointer++;
}
return NULL;
}
char *strtok_r(char *str, const char *delim, char **saveptr)
{
char *local_pointer;
char *delim_char,*return_pointer;
if(!delim)
return NULL;
if(str)
{
*saveptr=str;
}
local_pointer=*saveptr;
if(!local_pointer)
return NULL;
return_pointer=local_pointer;
while(*local_pointer!='\0')
{
if(isdelim(local_pointer,delim))
{
*local_pointer='\0';
local_pointer++;
*saveptr=local_pointer;
return return_pointer;
}
local_pointer++;
}
return NULL;
}
int main(int argc,char *argv[])
{
char str[] = "root:x::0:root:/root:/bin/bash:";
char *token,*token_return,*token_save;
for(token=str;;token=NULL)
{
token_return=strtok_r(token,":",&token_save);
if(!token_return)
break;
printf("%s\n", token_return);
}
return 0;
}
希望大家多指点!谢谢!int isdelem(char c, const char *split){
while(split!=NULL && *split != '\0'){
if(c == *split){
return 1;
}
split++;
}
return 0;
}
char* str_tok_r(char *str, const char *split, char **saveptr){
char* pstart;
char* pcur;
if(*saveptr != NULL){
if(**saveptr == '\0'){
str = NULL;
}else{
str = *saveptr;
}
}
while(str!=NULL && *str!='\0' && isdelem(*str, split)){
str++;
}
pstart = pcur = str;
while(pcur!=NULL && *pcur!='\0'){
if(!isdelem(*pcur, split)){
pcur++;
}else{
*pcur = '\0';
pcur++;
*saveptr = pcur;
break;
}
}
if(pcur!=NULL && *pcur == '\0'){
*saveptr = NULL;
}
return pstart;
}
貌似我写的很麻烦char* str_tok_r(char *str, const char *split, char **saveptr){
char* pstart;
char* pcur;
if(str == NULL){
str = *saveptr;
}
while(str!=NULL && *str!='\0' && isdelem(*str, split)){
str++;
}
pstart = pcur = str;
while(pcur!=NULL && *pcur!='\0'){
if(!isdelem(*pcur, split)){
pcur++;
}else{
*pcur = '\0';
pcur++;
*saveptr = pcur;
break;
}
}
if(pcur!=NULL && *pcur == '\0'){
*saveptr = NULL;
}
return pstart;
}
修正#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct _query_param{
char *key;
char *value;
struct _query_param *next;
} query_param;
typedef struct _url_node{
char *path;
query_param *param;
} url_node;
url_node *parse_url(char *url_path);
void print_url(url_node *node);
void free_url(url_node *node);
int main(void){
char *url_path = "http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=";
char *url_path2 = "http://www.baidu.com/s?wd=linux&cl=3";
url_node *node = parse_url(url_path);
print_url(node);
free_url(node);
return 0;
}
url_node *parse_url(char *url_path){
size_t len = strlen(url_path);
char *url_to_parse = (char *)malloc(sizeof(char)*len+1);
strcpy(url_to_parse, url_path);
char *url = strtok(url_to_parse, "?");
char *param = strtok(NULL, "?");
url_node *node = (url_node *)malloc(sizeof(url_node));
node->path = (char *)malloc(strlen(url)+1);
strcpy(node->path, url);
char *param_str;
char *saveptr1, *saveptr2;
while((param_str=strtok_r(param, "&", &saveptr1))!=NULL){
param = NULL;
query_param *new_param = (query_param *)malloc(sizeof(query_param));
char *param_key = strtok_r(param_str, "=", &saveptr2);
char *param_value = strtok_r(NULL, "=", &saveptr2);
if(param_key!=NULL){
new_param->key = malloc(strlen(param_key)+1);
strcpy(new_param->key, param_key);
}
if(param_value!=NULL){
new_param->value = malloc(strlen(param_value)+1);
strcpy(new_param->value, param_value);
}
query_param **p_param = &node->param;
query_param *last_param = node->param;
while(last_param!=NULL){
p_param = &last_param->next;
last_param = last_param->next;
}
*p_param = new_param;
}
free(url_to_parse);
return node;
}
void print_url(url_node *node){
printf("url path:%s\n", node->path);
query_param *param = node->param;
while(param!=NULL){
printf("key:%s\n", param->key);
printf("value:%s\n", param->value);
param = param->next;
}
}
void free_url(url_node *node){
free(node->path);
node->path = NULL;
query_param *last_param = node->param;
while(last_param!=NULL){
query_param *temp = last_param;
last_param = last_param->next;
free(temp);
}
free(node);
}
如果您有建设性意见,哪怕只是纠正一个错别字,也请不吝赐教,您留下的姓名和email将会出现在本书前言的致谢中。再次感谢您的宝贵意见!