【问题标题】:Why does my String array print different values than what i store into it为什么我的字符串数组打印的值与我存储的值不同
【发布时间】:2021-05-06 18:28:39
【问题描述】:

我正在尝试编写一个函数来遍历文件夹及其所有子文件夹以查找所有“stat”文件并打印前两个(按空格分隔)值。第一个值是整数,这没有问题。第二个值是一个字符串,打印该值给我带来了一些麻烦。我正在使用strtok() 获取每个文件的前两个值,并且我已经阅读了该函数的作用,因此信息的提取工作正常。但是,当我同时打印整数数组和字符串数组时,字符串根本不是最初存储的内容。

有问题的变量定义如下:

int pidsId = 0;
char delimiter[] = " ";
int* pids = malloc(sizeof(int) * 50);
char** names = malloc(sizeof(char*) * 20);
char* name = malloc(sizeof(char) * 20);
for(int i = 0; i < 20; i++) {
    names[i] = malloc(sizeof(char) * 20);
}

我在其中存储文件值的 while 循环:

while((sde = readdir(subdir)) != NULL) {
    if((sde->d_type == DT_REG) && !strcmp(sde->d_name, "stat")) {
        
        char* statline = malloc(sizeof(char) * 10);
        size_t statsize = 10;
        char* ime = malloc(strlen(subpath) + strlen(sde->d_name) + 2);

        strcpy(ime, subpath);
        strcat(ime, "/");
        statFile = fopen(strcat(ime, sde->d_name), "r");
        
        getline(&statline, &statsize, statFile);
        pids[pidsId] = atoi(strtok(statline, delimiter));
        name = strtok(NULL, delimiter);
        printf("%s\n", name);
        names[pidsId] = name;
                        
        printf("%s\n", names[pidsId]);
        pidsId++;
        free(statline);

        free(ime);

        fclose(statFile);
   }    
}

最后是问题所在:

for ( int i = 0; i < pidsId; i++) {
    printf("%d %s\n", pids[i], names[i]);
}

详细说明一下,当我保存字符串时,打印很好,但是在我将name 存储到names 数组中并且当我尝试打印它时,while 循环结束时字符串发生了一些事情。据我了解,printf("%s", char* array) 会打印出所有字符,直到遇到'\0'。而且我尝试使用与上述代码相同的方法(复制粘贴的数组定义和打印循环)打印一个简单的字符串数组,并且打印效果很好。

我已经尝试在互联网上四处寻找,但尚未找到解决方案。我尝试将我的数组定义更改为char names[][]char* names[],甚至尝试逐个字符地打印字符串。我一直在寻找打印字符串数组的问题,但到目前为止没有任何效果。这可能是因为我看了这么久的代码,但我看不出我做错了什么。我在这里想念什么?以下是所需输出的示例(while 循环中没有打印行):

16 (dash)
15 (dash)
20 (copyproc.sh)
12 (sleep)
10 (bash)
1 (bash)
14 (dash)
11 (sleep)

我得到了这个(在 while 循环中没有打印行):

16 
15 ��U
20 
12 
10 ��U
1 ��U
14 ��U
11 ��U

感谢任何有助于理解我的问题的帮助。

【问题讨论】:

    标签: arrays c string


    【解决方案1】:

    在您的代码中,“名称”指向stateline 的一部分。这是由 strtok 保证的。但是,您在函数中执行free(stateline),也会使name 无效。

    我建议您在释放“状态线”之前复制“名称”,例如使用 strdup:

     names[pidsId] = strdup(name);
    

    【讨论】:

    • 我明白了,我不认为它会那样工作,但这很有趣。无论如何,它解决了我的问题,谢谢你好心的陌生人。
    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 2020-07-18
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    相关资源
    最近更新 更多