我试图在C中的解析例程中发现错误。代码是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
static const char * month_abb_names[] =
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
static const char * wday_abb_names[] =
{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
};
time_t mb_mktime(char * time_str)
{
struct tm msg_time;
char * cur, * next, *tmp_cur, *tmp_next, oldval;
int counter = 0, tmp_counter = 0, i;
int cur_timezone = 0, sign = 1;
time_t retval;
msg_time.tm_isdst = 0;
cur = time_str;
next = strchr(cur, ' ');
while(next)
{
oldval = (*next);
(*next) = '\0';
switch(counter)
{
case 0 :
// day of week
for(i = 0; i < 7; i++)
{
if(strncasecmp(cur, wday_abb_names[i], 3) == 0)
{
msg_time.tm_wday = i +1;
break;
}
}
break;
case 1 :
//month name
for(i = 0; i < 12; i++)
{
if(strncasecmp(cur, month_abb_names[i], 3) == 0)
{
msg_time.tm_mon = i;
break;
}
}
break;
case 2 :
// day of month
msg_time.tm_mday = strtoul(cur, NULL, 10);
break;
case 3 :
// HH:MM:SS
tmp_cur = cur;
tmp_next = strchr(cur, ':');
tmp_counter = 0;
while(tmp_next)
{
switch(tmp_counter)
{
case 0 :
msg_time.tm_hour = strtoul(tmp_cur, NULL, 10);
break;
case 1 :
msg_time.tm_min = strtoul(tmp_cur, NULL, 10);
break;
}
tmp_cur = tmp_next + 1;
tmp_next =strchr(tmp_cur, ':');
tmp_counter++;
}
msg_time.tm_sec = strtoul(tmp_cur, NULL, 10);
break;
case 4 :
// timezone
if( (*cur) == '+')
{
cur++;
}
else if ( (*cur) == '-')
{
sign = -1;
cur++;
}
cur_timezone = (int)strtol(cur, NULL, 10);
cur_timezone = sign * (cur_timezone / 100) * 60 * 60 + (cur_timezone % 100) * 60;
break;
}
(*next) = oldval;
cur = next + 1;
next = strchr(cur, ' ');
counter++;
}
// what's left is year
msg_time.tm_year = strtoul(cur, NULL, 10) - 1900;
#ifndef __WIN32
retval = timegm(&msg_time) - cur_timezone;
#else
retval = mktime(&msg_time) - cur_timezone; // + some adjustments....
#endif
printf("final msg_time = %ld\n", retval);
return retval;
}
void getTime(char * time_str)
{
time_t time = mb_mktime(time_str);
struct tm *ts;
char buf[80];
/* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz" */
ts = localtime(&time);
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
printf("%s --> %s\n", time_str, buf);
}
int main()
{
getTime("Thu Jun 16 04:53:00 +0000 2011");
printf("done.");
return 0;
}
main
和getTime
是新的,mb_mktime
只是略有修改
但是,行((*next) = '\0';
)会产生SIGSEGV。我承认我很不确定为什么代码看起来像这样......
然而,代码在普通应用程序中运行良好。
有人可以解释为什么这个代码在一个应用程序中工作而SIGSEGV在另一个应用程序中工作?
答案 0 :(得分:4)
您不应该修改常量字符串文字,在此示例中为"startstring"
。我认为正常的应用程序是有效的,因为那里使用的char缓冲区是可变的。