我使用以下代码在C中拆分char数组:
char line[100];
int number_of_gga_parsed = 0;
int gga_blocks_allocated;
gga_sentence *ggas_parsed;
gsa_sentence gsa;
gsv_sentence gsv;
ggas_parsed = malloc(10*sizeof(gga_sentence));
gga_blocks_allocated = 10;
if(ggas_parsed == NULL){
printf("error allocating memory, system exiting.\n");
exit(EXIT_FAILURE);
}
while(fscanf(stream, "%s", line)!= EOF){
strcpy((ggas_parsed + number_of_gga_parsed)->untouched_sentence, line);
initiate_gga_values((ggas_parsed + number_of_gga_parsed),(ggas_parsed + number_of_gga_parsed)->untouched_sentence);
}
initiate_gga_values功能:
void initiate_gga_values(gga_sentence* gga_ptr, const char* sentence){
char *temp_sentence;
char *token;
int token_no = 0;
/*Copy the gga_sentence into the temp_sentence char array*/
strcpy(temp_sentence, sentence);
token = strsep (temp_sentence,",");
while (token != NULL) {
switch(token_no){
case 0:
gga_ptr->sentence_id = token;
break;
case 1:
/*atoi converts a string to an int, well a c string anyways so a char* */
gga_ptr->time_stamp = atoi(token);
break;
case 2:
/*strtod coverts a string to a double, well a c string anyways so a char* */
gga_ptr->latitude = strtod(token, NULL);
break;
case 3:
gga_ptr->north_south_id = (char)token;
break;
case 4:
gga_ptr->longitude = strtod(token, NULL);
break;
case 5:
gga_ptr->east_west_id = (char)token;
break;
case 6:
gga_ptr->quality = atoi(token);
break;
case 7:
gga_ptr->no_of_satellites = atoi(token);
break;
case 8:
gga_ptr->horizontal_dillution = strtod(token, NULL);
break;
case 9:
gga_ptr->altitude = strtod(token, NULL);
break;
case 10:
gga_ptr->altitude_units = (char)token;
break;
case 11:
gga_ptr->geodial_seperation = strtod(token, NULL);
break;
case 12:
gga_ptr->geodial_seperation_units = (char)token;
break;
case 13:
gga_ptr->age_of_data_in_seconds = strtod(token, NULL);
break;
case 14:
gga_ptr->checksum = token;
break;
}
token_no++;
token = strsep (temp_sentence, ",");
}
}
char数组包含以下信息:
$GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72
但是当上面的代码运行时,我得到一个分段错误:
Segmentation fault (core dumped)
gga struct:
typedef struct gga_sentence{
char untouched_sentence[100];
gsa_sentence gsa;
char *sentence_id;
int time_stamp;
double latitude;
char north_south_id;
double longitude;
char east_west_id;
int quality;
int no_of_satellites;
double horizontal_dillution;
double altitude;
char altitude_units;
double geodial_seperation;
char geodial_seperation_units;
double age_of_data_in_seconds;
char *checksum;
}gga_sentence;
分段错误发生在函数initiate_gga_values函数完成之前,甚至是真正启动的。这意味着我假设gga_sentences的mallocing存在问题,但我看不到哪里!
这是我第一次使用strsep,所以毫无疑问我做错了。
gdb错误消息:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7de4103 in _dl_lookup_symbol_x (undef_name=0x4004d8 "strlen", undef_map=0x7ffff7ffe268,
ref=ref@entry=0x7fffffffdbb8, symbol_scope=0x302e312c362e312c, version=0x7ffff7ff9a08,
type_class=type_class@entry=1, flags=1, skip_map=skip_map@entry=0x0) at dl-lookup.c:733
733 dl-lookup.c: No such file or directory.
干杯, 克里斯。
答案 0 :(得分:3)
char *temp_sentence;
char *token;
int token_no = 0;
/*Copy the gga_sentence into the temp_sentence char array*/
strcpy(temp_sentence, sentence);
您没有为temp_sentence分配任何内存来保存复制的字符串
答案 1 :(得分:0)
token = strsep (&temp_sentence,",");
strsep
将char**
作为第一个参数。
答案 2 :(得分:0)
您正在将sentence
复制到未初始化的内存:
char *temp_sentence;
/* ... */
strcpy(temp_sentence, sentence);
temp_sentence
是一个未初始化的指针,指向某个随机位置,但不指向任何额外的内存。要解决此问题,您可以在堆栈上分配一定数量的字符,例如:
char temp_sentence[100];
strncpy(temp_sentence, sentence, sizeof(temp_sentence) - 1);
这可能会缩短您的字符串。另一种方法是在堆上分配输入字符串的副本:
char *temp_sentence = strdup(sentence);
在这种情况下,在从函数返回之前,必须使用free(temp_sentence)
释放已分配的内存。在任何一种情况下,您都需要一个可以传递给strsep
的第二个指针:
char *ptr = temp_sentence;
此指针需要可修改,因此您无法使用数组。如果临时字符串分配有strdup
,则需要保留原始指针,以便释放内存。
编辑:正如Arjun Sreedharan已经指出的那样,您应该将指向char的指针作为strsep
的第一个参数传递。这样,指针就会更新并引用尚未解析的其余字符串。
指针类型不匹配应该真正给出警告信息。你启用了警告吗?
无论如何,这里有一个简短的工作示例,说明你想要做什么,但没有实际的解析:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
const char* sentence = "$GPGGA,151019.000,5225.9627,N,"
"00401.1624,W,1,09,1.0,38.9,M,"
"51.1,M,,0000*72";
char *tmp = strdup(sentence); // modifiable copy
char *p = tmp; // pointer into copy for strsep
char *token;
int token_no = 0;
token = strsep(&p, ",");
while (token != NULL) {
printf("%d: '%s'\n", token_no, token);
token_no++;
token = strsep(&p, ",");
}
free(tmp); // release ressources of copy
return 0;
}