(1)给定如下面形式的字符串:“ad,app,ai,apk”,"bed book bool bat byte",它们由一组由固定字符隔开的字符串组合而成。
如何将长字符串分割,即去掉其中的空格或逗号,使能够取出其中单个的字符串?
(2)数字既能以字符串形式储存,也能以数值形式储存。把数字储存成字符串储存的就是数字字符,例如可以将213以‘2’、‘1’、‘3’、‘\0’的形式储存在一个字符串数组中。而以数值形式储存213,储存的是int类型的值。
假设程序需要使用数值命令形参,但是命令形参被读取为字符串。因此,要使用数值必须先把字符串转换为数字。
实例:这个txt文档中所有的SEED行是32个16进制数“0XAA”形式的文本,中间都以‘,’隔开,读取文件时数字以字符串形式储存,现需要取出SEED行所有的16进制数字的数值。
下面的程序实现了将所有数值取出,并将这些数重新以16进制形式写入一个新的txt文档中,新的文档格式如下
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SEEDNUM 10
typedef struct {
char **str; //the PChar of string array
size_t num; //the number of string
}IString;
int Split(char *src, char *delim, IString* istr);
int main(int argc, char *argv[])
{
FILE * sfp = NULL;
FILE * ofp = NULL;
sfp = fopen("10seed1122test.txt", "r");
ofp = fopen("10output1122.txt", "w");
if (NULL == sfp) /* 如果失败了 */
{
printf("错误!seed文件打开失败!");
exit(EXIT_FAILURE); /* 中止程序 */
}
if (NULL == ofp) /* 如果失败了 */
{
printf("错误!output文件打开失败!");
exit(EXIT_FAILURE); /* 中止程序 */
}
int i;
long value[32];
char * end;
unsigned char tem_buf[1024];
unsigned char dest_buf[1024];
for ( i = 0; i < SEEDNUM * 2; i++)
{
unsigned char output[32];
fgets(tem_buf, 1024, sfp);
if (i % 2)
{
strncpy(dest_buf, tem_buf + 5, 161);
IString istr;
Split(dest_buf, ",", &istr);
int j;
unsigned char tem[32];
for (j = 0; j < 32; j++)
{
char dest[2];
strncpy(dest, istr.str[j] + 2, 2);
value[j] = strtol(dest, &end, 16);
fprintf(ofp,"%02X",value[j]);
}
fprintf(ofp, "\n");
}
}
return 0;
}
int Split(char *src, char *delim, IString* istr)//split buf
{
int i;
char *str = NULL, *p = NULL;
(*istr).num = 1;
str = (char*)calloc(strlen(src) + 1, sizeof(char));
if (str == NULL) return 0;
(*istr).str = (char**)calloc(1, sizeof(char *));
if ((*istr).str == NULL) return 0;
strcpy(str, src);
p = strtok(str, delim);
(*istr).str[0] = (char*)calloc(strlen(p) + 1, sizeof(char));
if ((*istr).str[0] == NULL) return 0;
strcpy((*istr).str[0], p);
for (i = 1; p = strtok(NULL, delim); i++)
{
(*istr).num++;
(*istr).str = (char**)realloc((*istr).str, (i + 1)*sizeof(char *));
if ((*istr).str == NULL) return 0;
(*istr).str[i] = (char*)calloc(strlen(p) + 1, sizeof(char));
if ((*istr).str[0] == NULL) return 0;
strcpy((*istr).str[i], p);
}
free(str);
str = p = NULL;
return 1;
}
此外,使用string.h库里的strtok函数也能用于分割字符串,strtok函数的用法有点不寻常,参考以下程序,可以达到与上面程序相同的效果。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SEEDNUM 10
int main (void)
{
const char * delim = ",";
FILE * sfp = NULL;
FILE * ofp = NULL;
sfp = fopen("10seed1122test.txt", "r");
ofp = fopen("strtok10output1122.txt", "w");
if (NULL == sfp) /* 如果失败了 */
{
printf("错误!seed文件打开失败!");
exit(EXIT_FAILURE); /* 中止程序 */
}
if (NULL == ofp) /* 如果失败了 */
{
printf("错误!output文件打开失败!");
exit(EXIT_FAILURE); /* 中止程序 */
}
int i;
for (i=0;i<SEEDNUM*2;i++)
{
char *pt;
char tem_buf[512];
fgets (tem_buf,512,sfp);
if (i%2)
{
pt = strtok(tem_buf+5,delim);
int j;
for(j=0; j<32 && pt; j++)
{
long value[32];
char *temp;
char *end;
temp = pt+2;
value[j] = strtol(temp, &end, 16);
fprintf(ofp,"%02X",value[j]);
pt = strtok(NULL,delim);
}
fprintf(ofp,"\n");
}
}
return 0;
}