【问题标题】:strtok disappearing when returning -1返回-1时strtok消失
【发布时间】:2013-10-04 08:17:05
【问题描述】:

所以我正在编写将字符串放入数组的代码,并且它运行良好,但是我希望它在我点击文件中的 ## 时终止字符串的读取。我正在运行一个循环并逐行解析字符串。在我的字符串解析器中,我放置了一个循环来检查##。它在我的解析器函数的最后,它是:

for (i = 0; i < strlen(line)); i++)
{
    if ((buffer[i] == '#') && (buffer[i+1] == '#'))
    {
        return -1;
    }
}

问题是,当它到达最后带有## 的行时,它不会将字符串解析到我的数组中。似乎只是忽略了此循环之前的代码。

作为附加信息,我使用 strtok 将标记放在我的 char* 数组中的位置,然后再进行 for 循环。

编辑:这是我的 parseString 函数:

int parseString(char* line, char*** inString)
{
    char* buffer;
    int Token, i;

    buffer = (char*) malloc(strlen(line) * sizeof(char));
    strcpy(buffer,line);
    (*inString) = (char**) malloc(MAX_TOKS * sizeof(char**));

    Token = 0;  
    (*inString)[Token++] = strtok(buffer, DELIMITERS);

    while ((((*inString)[token] = strtok(NULL, DELIMITERS)) != NULL) && (Token < MAX_TOKS))
        Token++;

    for(i=0; i<strlen(line); i++)
    {
        if ((buffer[i] == '#') && (buffer[i+1] == '#'))
        {
            return -1;
        }            
    }
    return Token;
}

【问题讨论】:

  • 请不要在 for 循环条件中调用 strlen(line) 并尝试更好地格式化您的代码。
  • 如果 i == 0,它不会在缓冲区 [i-1] 上崩溃吗?
  • 我们能看到剩下的代码吗?前提是它不是很大。
  • 我刚刚进行了编辑,以便您可以看到该函数的整个代码。
  • 天哪。你知道你可以在一个块中标记多行代码吗?

标签: c arrays token strtok


【解决方案1】:

首先,您读取的数组越界,因为array[-1] 不好。其次,使用一个变量来保存字符串长度,因为这样做会导致 for 循环为每次迭代重新评估 strlen(line)。

现在,对于您的问题,您似乎将它放在 将其添加到数组的代码之前。如果你能给我们更多的代码,那会有所帮助。

【讨论】:

    【解决方案2】:

    缓冲区分配不足

    // buffer = (char*) malloc(strlen(line) * sizeof(char));
    buffer = malloc(strlen(line) + 1);  // +1 for the \0
    strcpy(buffer,line);
    

    内存泄漏

    分配的“缓冲区”可能会丢失。 *inString array_ 有一个指向“缓冲区”开头的指针,允许在调用例程中释放它,但这是不确定的。建议使用*inString 的第一个元素显式保存该缓冲区。

    算法漏洞

    (*inString)[token-1] == NULL 应该在for() 之前声明。

    O(n*n) 通过 strlen()

    建议:

    // for(i=0; i<strlen(line); i++)
    int length = strlen(line); // `length` should be used in `malloc()` too.
    for(i=0; i<length; i++)
    

    OP 的早期编辑方法几乎没问题

    只需要从 1 开始索引,而不是 0。不需要测试 i 的每个索引 line,但是 (length-1)。所以(i = 1; i&lt;length; i++) 或(i = 0; i&lt;length-1; i++)。

    // for (i = 0; i < strlen(line)); i++) {
    int length = strlen(line);
    for (i = 1; i<length; i++) { // start at 1
      if ((buffer[i-1] == '#') && (buffer[i] == '#')) {
        return -1;
      }
    }
    

    为了更好的帮助,建议OP提供样本line、line with the ## at the end、MAX_TOKS和DELIMITERS。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多