除非在分配时打印该值,否则 Char 数组值将打印为空 - C

标签 c arrays char printf

我正在我的 C 程序中使用两个函数,但无法让它们合作。我的第一个函数迭代 csv 文件并使用 strtok() 根据“,”分隔符分隔标记。每个标记都保存到大小为 3 的字符数组中,如果特定标记与目标标记不匹配,则读取下一行输入,标记化,并用新的输入标记覆盖字符数组。

这是使用的全局变量:

char * stateCityZip[3];

这是第一个函数的代码:

int zipToCity(char * zip)
{
char line[1024];
char * tok = malloc(20 * sizeof(char));
FILE * file = fopen("cityzip.csv", "r");
while (fgets(line, sizeof(line), file))
{
    //State
    tok = strtok(line, ",");
    stateCityZip[0] = tok;
    //City
    tok = strtok(NULL, ",");
    stateCityZip[1] = tok;
    //Zip
    tok = strtok(NULL, ",");
    stateCityZip[2] = tok;

    if (strcmp(stateCityZip[2], newZip) == 0) {
        //printf("Found %s, %s\n", stateCityZip[0], stateCityZip[1]);
        strlen(stateCityZip[1]));
        return 1;
    }
}
return 0;
}

我的第二个函数只是尝试打印 stateCityZip 的值。然而,当我打印这些值时,它们显示为空白。我发现解决这个问题的唯一方法是取消注释

//printf("Found %s, %s\n", stateCityZip[0], stateCityZip[1]);

线。

这是我的第二个函数的代码:

int main() {
    printf("City: [%s]", stateCityZip[1]);
    printf("State: [%s]", stateCityZip[0]);

    return 0;
}

输出:

City: []
State: []

最佳答案

strtok 返回指向其输入的子字符串的指针。因此,您的所有 tok 值都是指向 line 部分的指针,该部分具有自动存储期限,因此 stateCityZip 中的指针一旦 zipToCity 返回。

(实际上,如果文件中有多于一行,一旦您前进到下一行,tok 指针就会全部失效,因为它们现在指向新行的任意子字符串缓冲区中的行。)

相反,您应该使用 strdup 将 token 的副本分配为新字符串,并将从 strdup 返回的指针保存到 stateCityZip >.

重要提示:由strdup分配的字符串需要由free释放。如果stateCityZip是全局的,那么你可以不释放它们(当你的进程退出时,最后的内存将被释放)。但是,如果再次调用 zipToCity,它将覆盖 stateCityZip 中的指针并泄漏相应的字符串。因此,最安全的做法可能是首先 free() stateCityZip 中的任何字符串(如果它们为 NULL,那就没问题,因为 free(NULL) code> 是一个无操作),然后再分配新值。

关于内存分配的主题:您的示例代码有一个对 tokmalloc 调用,这是完全多余的,并且肯定会泄漏,因为您覆盖了指针从malloc返回,而没有free它。

并且,关于良好的编码实践:fopen 可能会失败。您需要检查返回的 FILE * 是否不为 NULL。 (如果它是NULL,errno会告诉你原因。)并且你还需要fclose你没有出现的FILE *要么做。

更一般地说:这些代码似乎根本没有进行任何错误检查。每次调用任何标准库函数(或任何函数,就此而言!)时,您都需要考虑该函数如何无法完成其应做的事情,您将如何能够告诉(通常失败行为都有详细记录,因此请务必阅读文档),以及如果失败,您希望程序执行什么操作。如果文件不存在或无法读取怎么办?如果它包含不是以逗号分隔的行,或者不包含预期数量的字段?如果在处理文件的过程中内存不足,或者由于堆内存不足而 strdup 无法复制字符串,会发生什么情况?如果你不考虑这些问题,或者忘记处理它们,你可能会在一切正常的“幸福情况”中侥幸逃脱,但迟早它会回来咬你——通常是最坏的情况可能的时间。

关于除非在分配时打印该值,否则 Char 数组值将打印为空 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52390791/

相关文章:

c - 尝试将程序的执行时间存储到数组中,但数组元素始终显示相同的值

android - BLE 设备名称无法恢复

c - C 中 char 指针的问题

c++ - Win32 编辑控件为每个新行显示 '|' 类似符号

c - 为什么基本算术运算符不需要 math.h 库

在信号处理程序中创建线程

C: 为什么 C 或 C++ 中不允许 int[] 数组

c - WinMain 中 hPrevInstance 的作用是什么

c - 反函数正常工作,但如果在 while 循环后工作,它会产生错误的答案

c++ - 连接字符*