数组的静态索引会改变数组吗?

时间:2015-06-21 08:38:31

标签: c arrays

我想使用strtok将路径名称分成序列。但是我提出了一个问题,我的代码如下所示:

int main(void)
{
    char test[] = "/hoe/wahoo/Documents/hello/test";
    char *str[8]; 
    int index = 0;
    int count = 0;

    str[index] = strtok(test, "\\/");
    while (str[index] && *str[index]) {
        index++;
        str[index] = strtok(NULL, "\\/");
    }

    for (index=0; index<8; index++) {
        if (str[index] && *str[index]) {
            count++;
        }
    }

    printf("%d\n", count);

    return 0;
}

显然,我收到错误segmentation error,我知道错误的来源。一次,我将第5行中的int index = 0;更改为static index = 0;。我发现它确实有用!!

为什么?似乎我将数组的索引更改为静态,即数组将是静态的。

3 个答案:

答案 0 :(得分:4)

在第一个循环中,您仔细检查非空ptr:

str[index] = strtok(test, "\\/");
while (str[index] && *str[index]) {
    index++;
    str[index] = strtok(NULL, "\\/");
}

但是在你的第二个循环中你没有,并且你没有初始化str来获得值,这会引入未定义的行为。这就是为什么当你改变一些其他变量时,例如通过将一个变为静态变量,会发生不同的行为。

for (index=0; index<8; index++) {
    if (str[index] && *str[index]) {
        count++;
    }
}

这个循环需要是:

for (index = 0; str[index] && *str[index]; ++index) {
    ++count;

或者更好的是,你可以把整个写成

int main(void)
{
    char test[] = "/hoe/wahoo/Documents/hello/test";
    char *str[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
    int count = 0;

    str[count] = strtok(test, "\\/");
    while (str[count] && *str[count]) {
        str[++count] = strtok(NULL, "\\/");
    }

    printf("%d\n", count);
}

---编辑---

另请注意,strtok会修改原始字符串。完成循环后,test中的路径separtors将替换为'\ 0'。

答案 1 :(得分:3)

这与静态变量无关。您只需要初始化 echo "<div class='shoe-view'>"; echo "<img class='show-view-image' src='scripts/shoes/uploads/".$result["imagename"]."' alt='".$result["imagename"]."'/>"; echo "<p class='sub-heading desc catalogfont' style='color:rgb(184, 55, 60);'>".$result["shoename"]."</p>"; echo "<p class='content catalogfont' style='font-weight:bold;'>".$result["price"]."</p>"; echo "<p class='content catalogfont' style='font-weight:bold;'>".$result["Color"]." : ".$result["brand"]."</p>"; echo "<form action='buyshoe.php' method='post'>"; echo "<button value='".$result["id"]."' name='messagebutton' class='send-message'>Buy Shoe</button>"; echo "</form>"; echo "</div>"; ,否则未使用的元素将包含随机垃圾,您将获得未定义的行为(很可能是因为您尝试迭代超出数组的末尾)。

请注意,未定义的行为是未定义的行为 - 当您执行此类操作时,字面上会出现任何。对代码中不相关区域的随机更改可能会影响观察到的结果,但这实际上只是一种分心,并没有解决潜在的问题。

所以改变:

str[]

为:

char *str[8]; 

一切都会好的。

答案 2 :(得分:0)

你已经得到了一个很好的答案。

这是另一段代码:

#include <string.h>
#include <stdio.h>

int main()
{
    char test[] = "/hoe/wahoo/Documents/hello/test";
    char delims[] = "\\/";
    char *str[8]; 
    int count = 0;

    str[0] = strtok(test, delims);
    while (str[count]) {
        printf("%s,", str[count]);
        count++;
        str[count] = strtok(NULL, delims);
    }

    printf("\n%d\n", count);
    return 0;
}

输出:

hoe,wahoo,Documents,hello,test,
5

请注意:这是可读的,但效率很低,因为它使用索引来处理str中的元素。

以下是我要编写的内容(指针为您提供优势):

int main()
{
    char test[] = "/hoe/wahoo/Documents/hello/test";
    char delims[] = "\\/";
    char *str[8];
    char **p = str;
    int count = 0;

    *p = strtok(test, delims);
    while (*p) {
        printf("%s,", *p);
        count++;
        *(++p) = strtok(NULL, delims);
    }

    printf("\n%d\n", count);
    return 0;
}

注意:上面的所有代码都没有检查达到的最大令牌数。我建议将其添加以避免出现段错/不可预测的行为。