C語言 MOOC 單詞長度計算,GPS資訊處理 字串操作(函式,切分,尋找,轉換)
1.單詞長度
題目內容:
你的程式要讀入一行文字,其中以空格分隔為若干個單詞,以‘.’結束。你要輸出這行文字中每個單詞的長度。這裡的單詞與語言無關,可以包括各種符號,比如“it's”算一個單詞,長度為4。注意,行中可能出現連續的空格。
輸入格式:
輸入在一行中給出一行文字,以‘.’結束,結尾的句號不能計算在最後一個單詞的長度內。
輸出格式:
在一行中輸出這行文字對應的單詞的長度,每個長度之間以空格隔開,行末沒有最後的空格。
輸入樣例:
It's great to see you here.
輸出樣例:
4 5 2 3 3 4
#include <iostream> #include <stdio.h> #include <string.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char** argv) { char str[10][10]; int size=0,i; int lstLen; do{ scanf("%s",&str[size]); size++; }while(getchar()!='\n'); for(i=0;i<size-1;i++) printf("%d ",strlen(str[i])); //最後一個字元 lstLen=strlen(str[i])-1; printf("%d",lstLen); return 0; }
2.GPS資料處理
題目內容:
NMEA-0183協議是為了在不同的GPS(全球定位系統)導航裝置中建立統一的BTCM(海事無線電技術委員會)標準,由美國國家海洋電子協會(NMEA-The National Marine Electronics Associa-tion)制定的一套通訊協議。GPS接收機根據NMEA-0183協議的標準規範,將位置、速度等資訊通過串列埠傳送到PC機、PDA等裝置。
NMEA-0183協議是GPS接收機應當遵守的標準協議,也是目前GPS接收機上使用最廣泛的協議,大多數常見的GPS接收機、GPS資料處理軟體、導航軟體都遵守或者至少相容這個協議。
NMEA-0183協議定義的語句非常多,但是常用的或者說相容性最廣的語句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。
其中$GPRMC語句的格式如下:
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
這裡整條語句是一個文字行,行中以逗號“,”隔開各個欄位,每個欄位的大小(長度)不一,這裡的示例只是一種可能,並不能認為欄位的大小就如上述例句一樣。
欄位0:$GPRMC,語句ID,表明該語句為Recommended Minimum Specific GPS/TRANSIT Data(RMC)推薦最小定位資訊
欄位1:UTC時間,hhmmss.sss格式
欄位2:狀態,A=定位,V=未定位
欄位3:緯度ddmm.mmmm,度分格式(前導位數不足則補0)
欄位4:緯度N(北緯)或S(南緯)
欄位5:經度dddmm.mmmm,度分格式(前導位數不足則補0)
欄位6:經度E(東經)或W(西經)
欄位7:速度,節,Knots
欄位8:方位角,度
欄位9:UTC日期,DDMMYY格式
欄位10:磁偏角,(000 - 180)度(前導位數不足則補0)
欄位11:磁偏角方向,E=東W=西
欄位16:校驗值
這裡,“*”為校驗和識別符,其後面的兩位數為校驗和,代表了“$”和“*”之間所有字元(不包括這兩個字元)的異或值的十六進位制值。上面這條例句的校驗和是十六進位制的50,也就是十進位制的80。
提示:^運算子的作用是異或。將$和*之間所有的字元做^運算(第一個字元和第二個字元異或,結果再和第三個字元異或,依此類推)之後的值對65536取餘後的結果,應該和*後面的兩個十六進位制數字的值相等,否則的話說明這條語句在傳輸中發生了錯誤。注意這個十六進位制值中是會出現A-F的大寫字母的。
現在,你的程式要讀入一系列GPS輸出,其中包含$GPRMC,也包含其他語句。在資料的最後,有一行單獨的
END
表示資料的結束。
你的程式要從中找出$GPRMC語句,計算校驗和,找出其中校驗正確,並且欄位2表示已定位的語句,從中計算出時間,換算成北京時間。一次資料中會包含多條$GPRMC語句,以最後一條語句得到的北京時間作為結果輸出。
你的程式一定會讀到一條有效的$GPRMC語句。
輸入格式:
多條GPS語句,每條均以回車換行結束。最後一行是END三個大寫字母。
輸出格式:
6位數時間,表達為:
hh:mm:ss
其中,hh是兩位數的小時,不足兩位時前面補0;mm是兩位數的分鐘,不足兩位時前面補0;ss是兩位數的秒,不足兩位時前面補0。
輸入樣例:
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
END
輸出樣例:
10:48:13
注意:
由上篇複習字串陣列可知,最好不用指標表示字串,那麼對字串有修改操作的情況下,不寫成函式的形式,寫在主函式中
對於輸入END時結束,只需加一個迴圈即可,不做單獨寫入
#include <stdlib.h>
#include <stdio.h> //引入atoi()函式的所需
#include <string.h>
#define SIZE 12 //可自定義
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int UTCtoBJT(int UTC)
{
int BJT=UTC+80000;
if(BJT>235959) BJT-=BJT-240000;
return BJT;
}//轉換時間
void printBJT(char str[][SIZE])
{
char Utime[7],Btime[7];
int UTC,BJT;
int i;
for(i=0;i<strlen(str[1])&&str[1][i]!='.';i++)
Utime[i]=str[1][i];
UTC=atoi(Utime);
BJT=UTCtoBJT(UTC);
itoa(BJT,Btime,10);
//輸出時間
for(i=0;i<7;i++)
{
printf("%c",Btime[i]);
if((i+1)==2||(i+1)==4) printf(":"); //hh:mm:ss
}
}//輸出時間
int verifySum(char str[][SIZE])
{
int verf;
for(i=0;i<cnt-1;i++) //注意我們這裡的最後一個字串是已知校驗和
{
for(j=0;j<strlen(str[i]);j++)
verf=verf^str[i][j];
}
//printf("%x\n",verf);
return verf;
}//計算校驗和
int cmpStrAndInt(int num, int str[][SIZE])
{
char p[3];
int cmp;
itoa(num,p,16); //轉換為16進位制字串
cmp=strcmp(p,str[cnt-1]);
return cmp;
}//比較數字和字串
int main(int argc, char** argv) {
char gps[100];
char cmpstr[]="$GPRMC";
int cmp=1;
char str[20][SIZE]={"\0",}; //初始化
int cnt=0; //分組後的陣列大小
int verf=0; //驗證和
int i=0,j=0;
//僅當輸入開頭符合要求即cmp==0時錄入
while(cmp)
{
scanf("%s",&gps);
cmp=strncmp(gps,cmpstr,strlen(cmpstr));
}
//printf("%d\n",strlen(gps));
//切分字串陣列 類似java中split的功能
for(i=0;gps[j]!='\0';i++) //當讀入的字串結束時結束切分
{
int k=0;
for(j;j<strlen(gps);j++)
{
if(gps[j]==','||gps[j]=='*') //逗號切分,因為要將已知校驗和分開所以也要當做切分元素
{
j++;
break;
}
if(gps[j]=='$') //開頭字元不算
{
j++;
}
str[i][k]=gps[j]; //且分成字串組成的字串陣列
k++;
}
}
cnt=i;
//計算校驗和,比較校驗和以及定位欄位是否開放
verf=verifySum(str);
cmp=cmpStrAndInt(verf,str);
if(cmp==0)
cmp=strcmp(str[2],"A");
//將UTC->BJT
if(cmp==0)
printBJT(str);
return 0;
}
最後附上c語言字串函式的連結總結(不妥刪)https://www.cnblogs.com/lidabo/p/5225868.html