我正在从hackerrank那里遇到问题,这是问题所在:https://www.hackerrank.com/challenges/time-conversion/problem
tl; dr ,我们将像08:00:00 PM这样的时间转换为20:00:00
我从以下站点获得的str_split函数:Split string with delimiters in C
首先,这是我的完整代码:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
char** str_split(char* a_str, const char a_delim)
{
char** result = 0;
size_t count = 0;
char* tmp = a_str;
char* last_comma = 0;
char delim[2];
delim[0] = a_delim;
delim[1] = 0;
/* Count how many elements will be extracted. */
while (*tmp)
{
if (a_delim == *tmp)
{
count++;
last_comma = tmp;
}
tmp++;
}
/* Add space for trailing token. */
count += last_comma < (a_str + strlen(a_str) - 1);
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
result = malloc(sizeof(char*) * count);
if (result)
{
size_t idx = 0;
char* token = strtok(a_str, delim);
while (token)
{
assert(idx < count);
*(result + idx++) = strdup(token);
token = strtok(0, delim);
}
assert(idx == count - 1);
*(result + idx) = 0;
}
return result;
}
char* timeConverse(char* chr)
{
int del1 = 8;
int hour = 0;
char str[3];
char *result = malloc(10 * sizeof(str));
char** tokens;
char s[11];
for (int i = 0; i < 11; i++)
{
s[i] = *(chr + i);
}
bool time_of_day = 0; // 0 is morning, 1 is afternoon
tokens = str_split(s, ':');
char *endptr;
hour = strtol(*(tokens), &endptr, 10); // THE MAIN PROBLEM FOR SEGFAULT I THINK?
free(tokens);
// check if it is morning or afternoon
if (s[8] == 'P')
time_of_day = 1;
// if it is afternoon add 12 to hour
if (time_of_day)
{
hour += 12;
//
// remove the hour from the timer
memmove(&s[0], &s[0 + 1], strlen(s) - 0);
memmove(&s[0], &s[0 + 1], strlen(s) - 0);
// turn hour from int to string and store that to str
sprintf(str, "%d", hour);
}
// remove the last 2 element from the list (PM or AM)
s[strlen(s) - 1] = 0;
s[strlen(s) - 1] = 0;
// add hour to the min and second and store to result
sprintf(result, "%s%s", str, s);
// print out the result
return result;
free(result);
}
int main(void)
{
// this is just a test
char* time = "07:05:45PM";
char* result = timeConverse(time);
printf("%s\n", result);
return 0;
}
这是我关于黑客等级的代码:
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* readline();
/*
* Complete the timeConversion function below.
*/
/*
* Please either make the string static or allocate on the heap. For example,
* static char str[] = "hello world";
* return str;
*
* OR
*
* char* str = "hello world";
* return str;
*
*/
char **str_split(char *a_str, const char a_delim) {
char **result = 0;
size_t count = 0;
char *tmp = a_str;
char *last_comma = 0;
char delim[2];
delim[0] = a_delim;
delim[1] = 0;
/* Count how many elements will be extracted. */
while (*tmp) {
if (a_delim == *tmp) {
count++;
last_comma = tmp;
}
tmp++;
}
/* Add space for trailing token. */
count += last_comma < (a_str + strlen(a_str) - 1);
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
result = malloc(sizeof(char *) * count);
if (result) {
size_t idx = 0;
char *token = strtok(a_str, delim);
while (token) {
assert(idx < count);
*(result + idx++) = strdup(token);
token = strtok(0, delim);
}
assert(idx == count - 1);
*(result + idx) = 0;
}
return result;
}
char* timeConversion(char* chr) {
/*
* Write your code here.
*/
int del1 = 8;
int hour = 0;
char str[3];
char *result = malloc(10 * sizeof(str));
char **tokens;
char s[11];
for (int i = 0; i < 11; i++) {
s[i] = *(chr + i);
}
bool time_of_day = 0; // 0 is morning, 1 is afternoon
tokens = str_split(s, ':');
char *endptr;
hour = strtol(*(tokens), &endptr, 10);
free(tokens);
// check if it is morning or afternoon
if (s[8] == 'P')
time_of_day = 1;
// if it is afternoon add 12 to hour
if (time_of_day) {
hour += 12;
//
// remove the hour from the timer
memmove(&s[0], &s[0 + 1], strlen(s) - 0);
memmove(&s[0], &s[0 + 1], strlen(s) - 0);
// turn hour from int to string and store that to str
sprintf(str, "%d", hour);
}
// remove the last 2 element from the list (PM or AM)
s[strlen(s) - 1] = 0;
s[strlen(s) - 1] = 0;
// add hour to the min and second and store to result
sprintf(result, "%s%s", str, s);
// print out the result
return result;
free(result);
}
int main()
{
FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
char* s = readline();
char* result = timeConversion(s);
fprintf(fptr, "%s\n", result);
fclose(fptr);
return 0;
}
char* readline() {
size_t alloc_length = 1024;
size_t data_length = 0;
char* data = malloc(alloc_length);
while (true) {
char* cursor = data + data_length;
char* line = fgets(cursor, alloc_length - data_length, stdin);
if (!line) { break; }
data_length += strlen(cursor);
if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') { break; }
size_t new_length = alloc_length << 1;
data = realloc(data, new_length);
if (!data) { break; }
alloc_length = new_length;
}
if (data[data_length - 1] == '\n') {
data[data_length - 1] = '\0';
}
data = realloc(data, data_length);
return data;
}
它可以在我的PC上运行,但是当我在hackerrank上运行代码时,我将代码上传到timeConversion函数中,出现此错误:
GDB trace:
Reading symbols from solution...done.
[New LWP 11121]
Core was generated by `solution'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __GI_____strtol_l_internal (
nptr=0x5847d900 <error: Cannot access memory at address 0x5847d900>,
endptr=0x7ffd1f2ba350, base=10, group=<optimized out>,
loc=0x7f60be451560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
#0 __GI_____strtol_l_internal (
nptr=0x5847d900 <error: Cannot access memory at address 0x5847d900>,
endptr=0x7ffd1f2ba350, base=10, group=<optimized out>,
loc=0x7f60be451560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
#1 0x0000555a56bd0d43 in timeConversion (chr=<optimized out>)
at solution.c:89
#2 0x0000555a56bd0a4e in main () at solution.c:126
我假设hackerrank编译器与我的编译器计算机不同。 我使用编译代码 gcc(Debian 8.2.0-12)8.2.0。
答案 0 :(得分:2)
您的解决方案根本不需要str_split
只需替换
tokens = str_split(s, ';');
char *endptr;
hour = strtol(*(tokens), &endptr, 10); // THE MAIN PROBLEM FOR SEGFAULT I THINK?
free(tokens);
作者
char *endptr;
hour = strtol(s, &endptr, 10);
当然要删除char** tokens;
,也要删除int del1 = 8;
没用
答案 1 :(得分:1)
问题很可能是main()
中的这一行:
char* time = "07:05:45PM";
更改为:
char time[] = "07:05:45PM";
在您的解决方案中,time
是指向常量 constant 的指针,但是split_str()
对其进行了修改。
该解决方案通常设计过度;以下将起作用:
char* timeConversion(char* s)
{
if (s[0] == '1' && s[1] == '2' )
{
if( s[8] == 'A' )
{
s[0] = '0' ;
s[1] = '0' ;
}
}
else if( s[8] == 'P' )
{
s[0] += 1 ;
s[1] += 2 ;
}
s[8] = 0 ;
return s ;
}