1、strstr()
C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
#include <stdio.h>
#include <string.h>
int main() {
char dest[] = "Hello A World";
char sour[] = "A";
char sour1 = 'A';
char *temp;
int temp1;
temp=strstr(dest, sour);
printf("temp=%s\n",temp);
temp = strrchr(dest, sour1);
printf("temp=%s\n", temp);
temp1 = strcmp(dest, sour);
printf("temp=%d\n", temp1);
return 0;
}
输出:
如果没有查找到,返回null
//测试strstr
char dest[] = "Hello A World";
char sour[] = "A";
char sour1 = 'Z';
char *Temp;
int temp1;
Temp = strstr(dest, sour);
printf("Temp=%s\n", Temp);
Temp = strrchr(dest, sour1);
printf("Temp=%s\n", Temp);
temp1 = strcmp(dest, sour);
printf("temp1=%d\n", temp1);
2、strrchr() 和 strchr()
(1)strrchr()
#include "string"
char *strrchr( const char *str, int ch );
功能:函数返回一个指针,它指向字符ch 在字符串str末次/最后出现的位置,如果匹配失败,返回NULL。
extern int readpcv(const char *file, pcvs_t *pcvs)
{
pcv_t *pcv;
char *ext;
int i,stat;
trace(3,"readpcv: file=%s\n",file);
/*char *strrchr( const char *str, int ch );
功能:函数返回一个指针,它指向字符ch 在字符串str末次出现的位置,如果匹配失败,返回NULL。*/
if (!(ext=strrchr(file,'.'))) ext="";
if (!strcmp(ext,".atx")||!strcmp(ext,".ATX")) {
stat=readantex(file,pcvs);
}
else {
stat=readngspcv(file,pcvs);
}
读取接收机和卫星天线文件中,使用!
(2) strchr()
char *strchr(const char *str, int c)
参数
str -- 要被检索的 C 字符串。
c -- 在 str 中要搜索的字符。
返回值
该函数返回在字符串 str 中第一次出现字符 c 的位置,如果未找到该字符则返回 NULL。
C 库函数 char *strchr(const char *str, int c) 在参数 str 所指向的字符串中搜索第一次/开始位置出现字符 c(一个无符号字符)的位置。
示例代码:
#include <stdio.h>
#include <string.h>
int main ()
{
const char str[] = "http://www.runoob.com";
const char ch = '.';
char *ret;
ret = strchr(str, ch);
printf("|%c| 之后的字符串是 - |%s|\n", ch, ret);
return(0);
}
运行结果:
|.| 之后的字符串是 - |.runoob.com|
复制
3、strcmp()
#include <string.h>
int strcmp( const char *str1, const char *str2 );
功能:比较字符串str1 和 str2, 返回值如下:
返回值 |
解释 |
less than 0 |
str1 is less than str2 |
equal to 0 |
str1 is equal to str2 |
greater than 0 |
str1 is greater than str2 |
for (j = k = nf = 0; j < n; j++) {
ext = strrchr(infile[j], '.');
if (ext && (!strcmp(ext, ".rtcm3") || !strcmp(ext, ".RTCM3"))) {
strcpy(ifile[nf++], infile[j]);
}
else {
/* include next day precise ephemeris or rinex brdc nav */
ttte = tte;
if (ext && (!strcmp(ext, ".sp3") || !strcmp(ext, ".SP3") ||
!strcmp(ext, ".eph") || !strcmp(ext, ".EPH"))) {
ttte = timeadd(ttte, 3600.0);
}
else if (strstr(infile[j], "brdc")) {
ttte = timeadd(ttte, 7200.0);
}
nf += reppaths(infile[j], ifile + nf, MAXINFILE - nf, tts, ttte, "", "");
}
while (k < nf) index[k++] = j;
if (nf >= MAXINFILE) {
trace(2, "too many input files. trancated\n");
break;
}
}
简单总结下三个函数:
函数原型:
int strcmp( const char *str1, const char *str2 );
char *strrchr( const char *str, int ch );
char *strstr( const char *str1, const char *str2 );
看两点:str2参数不同,返回值不同;
strncpy()
C 库函数 char *strncpy(char *dest, const char *src, size_t n) 把 src 所指向的字符串复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。
https://www.runoob.com/cprogramming/c-function-strncpy.html
注:需要自己加上’\0‘;
4、定义一个指针数组,*ifile[MAXINFILE]
#define MAXINFILE 1000 /* max number of input files */
char *ifile[MAXINFILE] //指针数组
for (i=0;i<n;i++) {
if (!(ifile[i]=(char *)malloc(1024))) {
free(base_); for (;i>=0;i--) free(ifile[i]);
freepreceph(&navs,&sbss,&lexs);
return 0;
}
}
/* free prec ephemeris and sbas data -----------------------------------------*/
static void freepreceph(nav_t *nav, sbs_t *sbs, lex_t *lex)
{
int i;
trace(3,"freepreceph:\n");
free(nav->peph); nav->peph=NULL; nav->ne=nav->nemax=0;
free(nav->pclk); nav->pclk=NULL; nav->nc=nav->ncmax=0;
free(nav->fcb ); nav->fcb =NULL; nav->nf=nav->nfmax=0;
free(nav->seph); nav->seph=NULL; nav->ns=nav->nsmax=0;
free(sbs->msgs); sbs->msgs=NULL; sbs->n =sbs->nmax =0;
free(lex->msgs); lex->msgs=NULL; lex->n =lex->nmax =0;
for (i=0;i<nav->nt;i++) {
free(nav->tec[i].data);
free(nav->tec[i].rms );
}
free(nav->tec ); nav->tec =NULL; nav->nt=nav->ntmax=0;
if (fp_rtcm) fclose(fp_rtcm);
free_rtcm(&rtcm);
}
将指针数组中的每一个元素(指针),通过malloc函数,在堆区进行内存分配;如果分配任意一个没有分配成功,则free释放结构体变量(base_、ifile[i]、navs、sbss、lexs)
5、如果在VS中进行后处理,将ts、te设置为0,RTKLIB识别开始和结束时间在:
一般我们将其设置为0,如下所示:
gtime_t ts = { 0 }, te = { 0 };
当RTKLIB读取完obs、nav之后,
/* read obs and nav data -----------------------------------------------------*/
static int readobsnav(gtime_t ts, gtime_t te, double ti, char **infile,
const int *index, int n, const prcopt_t *prcopt,
obs_t *obs, nav_t *nav, sta_t *sta)
6、RTKLIB提供了Output Debug Trace (OFF Level1-5)
如果在VS中我们打开了Debug Trace,那么函数内部开始运行及将相关调试信息保存到文件中;调试开始的代码位于:
位于:static int execses(……)中
/* execute processing session ------------------------------------------------*/
static int execses(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt,
const solopt_t *sopt, const filopt_t *fopt, int flag,
char **infile, const int *index, int n, char *outfile)
{
FILE *fp;
prcopt_t popt_=*popt;
char tracefile[1024],statfile[1024],path[1024],*ext;
trace(3,"execses : n=%d outfile=%s\n",n,outfile);
/* open debug trace */
if (flag&&sopt->trace>0) {
if (*outfile) {
strcpy(tracefile,outfile);
strcat(tracefile,".trace"); //原输出文件名,后加.trace
}
else {
strcpy(tracefile,fopt->trace);
}
traceclose();
traceopen(tracefile); //开始对 trace文件进行写处理
tracelevel(sopt->trace);
}
位于:static int execses(……)中
/* solution statistics level (0:off,1:states,2:residuals) */
输出结果统计文件:
/* open solution statistics */
if (flag&&sopt->sstat>0) {
strcpy(statfile,outfile);
strcat(statfile,".stat");
rtkclosestat();
rtkopenstat(statfile,sopt->sstat);
}
7、strstr(infile[i],"%r")
C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
readpreceph函数中,如下代码片段:
/* read precise ephemeris files */
for (i=0;i<n;i++) {
if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
readsp3(infile[i],nav,0);
}
/* read precise clock files */
for (i=0;i<n;i++) {
if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
readrnxc(infile[i],nav);
}
/* read satellite fcb files */
for (i=0;i<n;i++) {
if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
if ((ext=strrchr(infile[i],'.'))&&
(!strcmp(ext,".fcb")||!strcmp(ext,".FCB"))) {
readfcb(infile[i],nav);
}
}
如果输入文件中,含有基站和流动站的通配符:
if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
8、reppath函数:
/* replace keywords in file path -----------------------------------------------
* replace keywords in file path with date, time, rover and base station id
* args : char *path I file path (see below)
* char *rpath O file path in which keywords replaced (see below)
* gtime_t time I time (gpst) (time.time==0: not replaced)
* char *rov I rover id string ("": not replaced)
* char *base I base station id string ("": not replaced)
* return : status (1:keywords replaced, 0:no valid keyword in the path,
* -1:no valid time)
* notes : the following keywords in path are replaced by date, time and name
* %Y -> yyyy : year (4 digits) (1900-2099)
* %y -> yy : year (2 digits) (00-99)
* %m -> mm : month (01-12)
* %d -> dd : day of month (01-31)
* %h -> hh : hours (00-23)
* %M -> mm : minutes (00-59)
* %S -> ss : seconds (00-59)
* %n -> ddd : day of year (001-366)
* %W -> wwww : gps week (0001-9999)
* %D -> d : day of gps week (0-6)
* %H -> h : hour code (a=0,b=1,c=2,...,x=23)
* %ha-> hh : 3 hours (00,03,06,...,21)
* %hb-> hh : 6 hours (00,06,12,18)
* %hc-> hh : 12 hours (00,12)
* %t -> mm : 15 minutes (00,15,30,45)
* %r -> rrrr : rover id
* %b -> bbbb : base station id
*-----------------------------------------------------------------------------*/
extern int reppath(const char *path, char *rpath, gtime_t time, const char *rov,
const char *base)
如果输入文件(file)中,含有通配符,则 reppath函数的目的就是将file[]文件名中的通配符进行替换,保存到rpath中;这个根据输入的文件名是否含通配符而定!
9、向量内积(点乘)和外积(叉乘)
概括地说,向量的内积(点乘/数量积)。对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,如下所示,对于向量a和向量b:
a和b的点积公式为:
这里要求一维向量a和向量b的行列数相同。注意:点乘的结果是一个标量(数量而不是向量)
向量的外积(叉乘)
概括地说,两个向量的外积,又叫叉乘、叉积向量积,其运算结果是一个向量而不是一个标量。并且两个向量的外积与这两个向量组成的坐标平面垂直。
定义:向量a与b的外积a×b是一个向量,其长度等于|a×b| = |a||b|sin∠(a,b),其方向正交于a与b。并且,(a,b,a×b)构成右手系。
特别地,0×a = a×0 = 0.此外,对任意向量a,a×a=0。
对于向量a和向量b:
a和b的外积公式为:
其中:
根据i、j、k间关系,有:
向量内积(点乘)和外积(叉乘)概念及几何意义
RTKLIB中 求向量范数:先内积,然后开方
/* euclid norm 欧几里得范数,说白了,就是同一个向量点乘后开方,求向量长度-----------------------------------------------------------------
* euclid norm of vector
* args : double *a I vector a (n x 1)
* int n I size of vector a
* return : || a ||
*-----------------------------------------------------------------------------*/
extern double norm(const double *a, int n)
{
return sqrt(dot(a,a,n));
}
RTKLIB叉乘实现:
/* outer product of 3d vectors 叉积 外积-------------------------------------------------
* outer product of 3d vectors
* args : double *a,*b I vector a,b (3 x 1)
* double *c O outer product (a x b) (3 x 1)
* return : none
*-----------------------------------------------------------------------------*/
extern void cross3(const double *a, const double *b, double *c)
{
c[0]=a[1]*b[2]-a[2]*b[1];
c[1]=a[2]*b[0]-a[0]*b[2];
c[2]=a[0]*b[1]-a[1]*b[0];
}
10、涉及的矩阵运算
#include <string.h>
void *memcpy( void *to, const void *from, size_t count );
功能:函数从from中复制count 个字符到to中,并返回to指针。 如果to 和 from 重叠,则函数行为不确定。
/* copy matrix -----------------------------------------------------------------
* copy matrix 将B矩阵的值,复制到A中,所以传入两个矩阵
* args : double *A O destination matrix A (n x m)
* double *B I source matrix B (n x m)
* int n,m I number of rows and columns of matrix
* return : none
*-----------------------------------------------------------------------------*/
extern void matcpy(double *A, const double *B, int n, int m)
{
memcpy(A,B,sizeof(double)*n*m);
}
11、setstr()
函数将 src字符串中长度为n的字串,复制给dst,长度必须小于strlen(dst),但是无论n为多少,dst的内容都被覆盖,详情见示例!
/* set string without tail space ---------------------------------------------*/
static void setstr(char *dst, const char *src, int n)
{
char *p=dst;
const char *q=src;
while (*q&&q<src+n) *p++=*q++;
*p--='\0';
while (p>=dst&&*p==' ') *p--='\0';
}
示例程序:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* set string without tail space ---------------------------------------------*/
static void setstr(char *dst, const char *src, int n)
{
char *p = dst;
const char *q = src;
while (*q&&q < src + n) *p++ = *q++;
*p-- = '\0';
while (p >= dst && *p == ' ') *p-- = '\0';
}
int main()
{
char A[] = "VVVVVVVV";
char B[] = "Am er ican Welcome";
setstr(A,B,strlen(A));
printf("A[]=%s\n", A);
printf("B[]=%s\n", B);
char C[] = "VVVVVVVV";
char D[] = "Am er ican Welcome";
setstr(C, D, 5);
printf("C[]=%s\n",C);
printf("D[]=%s\n",D);
return 0;
}
运行结果:
12、static int cmpobs(const void *p1,const void *p2)
其中cmpobs是C标准库的函数;函数的定义如下:
功能: 使用快速排序例程进行排序
头文件:stdlib.h
用法: void qsort(void* base, size_t num, size_t width, int(__cdecl*compare)(const void*,const void*));
参数:
- 待排序数组,排序之后的结果仍放在这个数组中
- 数组中待排序元素数量
- 各元素的占用空间大小(单位为字节)
- 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)
代码如下:
qsort(obs->data,obs->n,sizeof(obsd_t),cmpobs);
/* compare observation data -------------------------------------------------*/
static int cmpobs(const void *p1, const void *p2)
{
obsd_t *q1=(obsd_t *)p1,*q2=(obsd_t *)p2;
double tt=timediff(q1->time,q2->time);
if (fabs(tt)>DTTOL) return tt<0?-1:1;
if (q1->rcv!=q2->rcv) return (int)q1->rcv-(int)q2->rcv;
return (int)q1->sat-(int)q2->sat;
}
13、结构体中含有字符数组,用指向结构体的指针赋初值
结构体sta_t里面有 字符数组、int 、double类型;因此通过指向sta_t结构体类型的指针,对结构体进行初始化(赋初值)时,字符数组的名字是个地址,也即看作指针;因此,
*sta->name='\0'; //成员数组的名字是个地址,需要使用”*“解引用,即把‘\0’赋值给这个数组的第0个成员(首位置处)
或一般把字符串赋值给一个结构体成员,使用memcpy
示例代码:
#include <iostream>
using namespace std;
#define MAXANT 1024
typedef struct { /* station parameter type */
char name[MAXANT]; /* marker name */
char marker[MAXANT]; /* marker number */
char antdes[MAXANT]; /* antenna descriptor */
char antsno[MAXANT]; /* antenna serial number */
char rectype[MAXANT]; /* receiver type descriptor */
char recver[MAXANT]; /* receiver firmware version */
char recsno[MAXANT]; /* receiver serial number */
int antsetup; /* antenna setup id */
int itrf; /* ITRF realization year */
int deltype; /* antenna delta type (0:enu,1:xyz) */
double pos[3]; /* station position (ecef) (m) */
double del[3]; /* antenna position delta (e/n/u or x/y/z) (m) */
double hgt; /* antenna height (m) */
} sta_t;
/* initialize station parameter ----------------------------------------------*/
static void init_sta(sta_t *sta)
{
int i;
/* */
*sta->name = '\0'; // -> 优先级 高于 *
*sta->marker = '\0';
*sta->antdes = '\0';
*sta->antsno = '\0';
*sta->rectype = '\0';
*sta->recver = '\0';
*sta->recsno = '\0';
sta->antsetup = sta->itrf = sta->deltype = 0;
for (i = 0; i < 3; i++) sta->pos[i] = 0.0;
for (i = 0; i < 3; i++) sta->del[i] = 0.0;
sta->hgt = 0.0;
}
int main() {
sta_t Sta;
sta_t *sta = &Sta;
if (sta) init_sta(sta); /* station parameter type */
/*
char str[MAXANT];
*str = '\0';
*/
/*
char *p_str = str;
p_str = (char *)"字符数组";
*/
system("pause");
return 0;
}
14、getbits和getbitu函数
/* extract unsigned/signed bits ------------------------------------------------
* extract unsigned/signed bits from byte data
* args : unsigned char *buff I byte data
* int pos I bit position from start of data (bits)
* int len I bit length (bits) (len<=32)
* return : extracted unsigned/signed bits
*-----------------------------------------------------------------------------*/
extern unsigned int getbitu(const unsigned char *buff, int pos, int len)
{
unsigned int bits=0;
int i;
for (i=pos;i<pos+len;i++) bits=(bits<<1)+((buff[i/8]>>(7-i%8))&1u); //1U 表示无符号整型1
return bits;
}
extern int getbits(const unsigned char *buff, int pos, int len)
{
unsigned int bits=getbitu(buff,pos,len);
if (len<=0||32<=len||!(bits&(1u<<(len-1)))) return (int)bits;
return (int)(bits|(~0u<<len)); /* extend sign */
}
都是从多少位里面获取数据,getbitu是获取无符号32位的数据;getbits是获取32位有符号的数据。
其中,POS为起始位,len为位数长度;
示例代码:
#include <stdio.h>
/* extract unsigned/signed bits ------------------------------------------------
* extract unsigned/signed bits from byte data
* args : unsigned char *buff I byte data
* int pos I bit position from start of data (bits)
* int len I bit length (bits) (len<=32)
* return : extracted unsigned/signed bits
*-----------------------------------------------------------------------------*/
extern unsigned int getbitu(const unsigned char *buff, int pos, int len)
{
unsigned int bits = 0;
int i;
for (i = pos; i < pos + len; i++) bits = (bits << 1) + ((buff[i / 8] >> (7 - i % 8)) & 1u); //1U 表示无符号整型1
//printf("getbitu 函数 bits=%d\n", bits);
return bits;
}
extern int getbits(const unsigned char *buff, int pos, int len)
{
unsigned int bits = getbitu(buff, pos, len);
if (len <= 0 || 32 <= len || !(bits&(1u << (len - 1)))) return (int)bits;
return (int)(bits | (~0u << len)); /* extend sign */
}
/* get signed 38bit field ----------------------------------------------------*/
static double getbits_38(const unsigned char *buff, int pos)
{
return (double)getbits(buff, pos, 32)*64.0 + getbitu(buff, pos + 32, 6);
}
int main() {
//1005数据(基站位置)
unsigned char str[] = { 0XD3, 0X00, 0X13, 0X3E, 0XD7, 0XD3, 0X02, 0X02, 0X98, 0X0E, 0XDE, 0XEF, 0X34, 0XB4, 0XBD, 0X62, 0XAC, 0X09, 0X41, 0X98, 0X6F, 0X33, 0X36, 0X0B, 0X98 };
int i = 24, j, staid, itrf,messageID;
double rr[3], re[3], pos[3];
messageID= getbitu(str, i, 12); i += 12; //信息类型
staid = getbitu(str, i, 12); i += 12; //基准站ID
itrf = getbitu(str, i, 6); i += 6 + 4; //
rr[0] = getbits_38(str, i); i += 38 + 2; //天线位置X (ECEF坐标)
rr[1] = getbits_38(str, i); i += 38 + 2; //天线位置Y (ECEF坐标)
rr[2] = getbits_38(str, i); //天线位置Z (ECEF坐标)
printf("messageID=%d staid =%d\n", messageID, staid);
printf("ECEF下天线位置:%d %d %d\n", rr[0], rr[1], rr[2]);
system("pause");
return 0;
}
运行结果:
15、setbits和setbitu函数
/* set unsigned/signed bits ----------------------------------------------------
* set unsigned/signed bits to byte data
* args : unsigned char *buff IO byte data
* int pos I bit position from start of data (bits)
* int len I bit length (bits) (len<=32)
* (unsigned) int I unsigned/signed data
* return : none
*-----------------------------------------------------------------------------*/
extern void setbitu(unsigned char *buff, int pos, int len, unsigned int data)
{
unsigned int mask=1u<<(len-1);
int i;
if (len<=0||32<len) return;
for (i=pos;i<pos+len;i++,mask>>=1) {
if (data&mask) buff[i/8]|=1u<<(7-i%8); else buff[i/8]&=~(1u<<(7-i%8));
}
}
extern void setbits(unsigned char *buff, int pos, int len, int data)
{
if (data<0) data|=1<<(len-1); else data&=~(1<<(len-1)); /* set sign bit */
setbitu(buff,pos,len,(unsigned int)data);
}
参考链接:
转载自:https://blog.csdn.net/wuwuku123/article/details/104836779
评论(0)
您还未登录,请登录后发表或查看评论