除非分配值,否则将字符数组值打印为空-C

时间:2018-09-18 16:18:34

标签: c arrays char printf

我正在c程序中使用两个函数,但是很难让它们合作。我的第一个函数遍历一个csv文件,并使用strtok()来基于“,”定界符来分隔标记。每个令牌都保存到大小为3的字符数组中,如果特定令牌与目标令牌不匹配,则会读取下一行输入并对其进行令牌化,然后用新的输入令牌覆盖字符数组。

以下是使用的全局变量:

def create_train_data():   
    a_int = np.random.randint(largest_number/2) # int version
    return a

np.random.seed(seed=int(time.time()))
for j in range(timesteps):
    c = create_train_data()

这是第一个功能的代码:

char * stateCityZip[3];

我的第二个功能只是尝试打印stateCityZip的值。但是,当我打印这些值时,它们显示为空白。解决此问题的唯一方法是取消对

的注释
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;
}

行。

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

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

输出:

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

    return 0;
}

1 个答案:

答案 0 :(得分:1)

strtok返回指向其输入的子字符串的指针。因此,您所有的tok值都是指向line的一部分的指针,这些指针具有自动存储持续时间,因此stateCityZip中的指针一旦zipToCity返回就全部失效。

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

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

重要说明:strdup需释放free分配的字符串。如果stateCityZip是全局的,那么您可以不用释放它们而逃脱(当进程退出时,最后的内存将被释放)。但是,如果再次调用zipToCity,它将覆盖stateCityZip中的指针并泄漏相应的字符串。因此,在分配新值之前,首先free()stateCityZip中的任何字符串(如果它们为NULL,则很好,因为free(NULL)是无操作)可能是最安全的。 / p>

关于内存分配:您的示例代码对malloc进行了tok调用,这是完全多余的,并且由于您覆盖了{{1}返回的指针,因此肯定会泄漏},而无需malloc对其进行编辑。

而且,关于良好的编码实践,free可能会失败。您需要检查返回的fopen是否为NULL。 (如果为NULL,FILE *会告诉您原因。)并且您还需要errno fclose,您似乎也没有这样做。

更一般地:此代码似乎根本都没有进行任何错误检查。每次调用任何标准库函数(或与此有关的任何函数!)时,您都需要考虑该函数可能无法完成应做的事情,如何做到告诉您(通常会很好地记录故障行为,因此请务必阅读文档),以及程序失败时要执行的操作。如果文件不存在或无法读取该怎么办?如果它包含没有逗号分隔的行,或者不包含预期的字段数?如果在处理文件的一半时间内存不足,或者FILE *由于堆内存不足而无法复制字符串,应该怎么办?如果您不考虑这些问题,或者忘记处理这些问题,则可以在一切正常的“快乐案例”中解决它,但迟早它会回来并咬住您-通常在最坏的情况下可能的时间。