2016-12-10 218 views
0

我试图通过定界符与此代码字符串分割到两个字符串由分隔符

int indexOf(char *msg, char c) { 
    int i; 
    for (i = 0; msg[i] != '\0'; i++) { 
     if (msg[i] == c) 
      return i; 
    } 
    return -1; 
} 

char *substring(char *msg, int startIndex, int endIndex) { 
    int length = endIndex - startIndex; 
    char *input = (char *)malloc(length * sizeof(char) + 1); 

    int i; 
    for (i = startIndex; i != endIndex; i++) { 
     input[i - startIndex] = msg[i]; 
    } 
    input[endIndex] = '\0'; 

    return input; 
} 

一个字符串分割成两个串在main我:

index = indexOf(msg, ':'); 

first = substring(line, 0, index - 1); 
second = substring(line, index + 2, strlen(line)); 

这段代码产生正确的输出,当我测试它与valgrind。在第二个变量中分配的子字符串会产生一个错误。

这个函数的问题在哪里?有另一种方法将字符串拆分为两个字符串吗?

char *msg = readMessage(stdin); 
index = indexOf(msg, '\n'); 
char *line, *first, *second; 

line = substring(msg, 0, index); 

末的valgrind Address 0x5203a52 is 5 bytes after a block of size 13 alloc'd

编辑:对于

index = indexOf(line, ':'); 

另一个bug现在Valgrind的错误是在子线input[endIndex] = '\0';

Invalid write of size 1 

编辑:我的代码解决方案有两个错误

在主

index = indexOf(msg, ':'); 

应该

index = indexOf(line, ':'); 

,并在子

input[endIndex] = '\0'; 

应该

input[length] = '\0'; 

感谢所有

+0

什么错误?顺便说一句,不要施加'malloc'返回。 – coredump

+0

您正在施放'malloc',如果不是'strlen(msg)'? '线路'在哪里进来? – t0mm13b

+0

可能会查看'strtok'?始终将指针变量初始化为NULL,以保持完整性。你有调试过吗? readMessage的代码是什么?我认为从函数返回的指针变量会因为在函数的堆栈中分配而被破坏。 – t0mm13b

回答

1

有在你的代码中的一些问题:

  • input[endIndex] = '\0';使用错误的索引。它应该是input[length] = '\0';

  • main(),你不应该暗示关于indexOf的返回值的假设。张贴的代码调用未定义的行为,如果:line发现:

这里是一个更安全的版本:

int index = indexOf(line, ':'); 
if (index >= 0) { 
    // found the `:` separator 
    char *first = substring(line, 0, index); 
    if (line[index + 1] == ' ') { 
     index++; // skip the space after the : 
    } 
    char *second = substring(line, index + 1, strlen(line)); 
    ... 
} 

可以使用strcspn()代替indexOf用更少的测试,以提取部分:

char *msg = readMessage(stdin); 
size_t index = strcspn(msg, "\n"); 
char *line = substring(msg, 0, index); 
... 

strcspn()返回高达但不包括其参数字符串中的字符d。如果字符存在(size_t类型,而不是int),它将返回与indexOf()相同的值,如果不是,则返回字符串的长度,这是您希望的情况。

+0

检查一行是否有':'我在其他代码中有 – mardon

+0

@mardon:4386427实际上在'main'函数中发现了一个错误。它应该是'index = indexOf(line,':');' – chqrlie

1
index = indexOf(msg, ':'); 
       ^^^ 
       line ? 

这里

second = substring(line, index+2, strlen(line)); 

您认为该行比指数+ 2更长。在malloc呼叫中应该检查一些内容以避免零。换句话说 - 如果分隔符是最后一个字符,则会遇到问题。

您应该添加由malloc

if (!input) 
{ 
    // Print error message 
    exit(1); 
} 

BTW返回值的检查 - 看看strdupmemcpystrncpy

+0

请不要提倡使用'strncpy'。 https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ – chqrlie

+0

@chqrlie - 终止问题是正确的。我不确定任何标准的C函数都能解决这个问题 - 你知道吗?您的链接通过编写使用C++的自定义函数来解决此问题。在C语言中使用'strncpy'来执行相同的操作。 – 4386427