虽然C中的循环分配不能按预期工作

时间:2016-10-30 14:07:33

标签: c sorting pointers while-loop

尝试打印从按字母顺序排列的文件中读取的所有名称。

let uniquePerformers = performances.reduce(Set<Performer>(), { (performers: Set<Performer>, performance) -> Set<Performer> in
    return performers.union(Set(performance.performers))
})

编译并运行程序会给我输出结果:

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

int compare(const void *a, const void *b){
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
}

int main(int argc, char* argv[]){

    //Takes input in terminal/cmd (filename.txt).
    char *input = malloc(sizeof(char) * 50);
    if (argc < 2){
        printf("Enter filename: ");
        scanf("%s", input);
    } else
        input = argv[1];
    //.......................


    int count = 0; //Names count
    char *names[100]; //Pointers to each name in file
    char str[50];
    FILE *file;
    file = fopen(input, "r");

    //Allocate space for the pointers
    for (int i = 0; i < 100;i++){
        names[i] = malloc(sizeof(char) * (50 + 1));
    }

    //Adding names to array
    if (file) {
        while ((fgets(str, 50, file)) != NULL){
            count++;
            names[count] = str;
            printf("%s", names[count]); //This will print names as read from file
        }      
        fclose(file);
        printf("%s", names[2]); //This will print the last name read with the while loop no matter the index of names[]

    } else printf("Can't read from file");

    //Sorting "names" in alphabetical order
    int length = sizeof(names)/sizeof(char*); //length of names
    qsort(names, length, sizeof(char*), compare);

    //printing each name (will be the last string read by while loop times the length)
    for(int i = 0; i < length; i++){
        printf("%s", names[i]);

    }
    printf("%d", count); //printing names count
}

显然我正在尝试按字母顺序对字符串进行排序。我目前的问题是,无论何时在while循环外打印 names [] ,指针都指向Haeltar,这是在while循环中分配的最后一个名字。我搜索得很远,但却无法弄清楚导致这种行为的原因。我对C编程比较陌生。

3 个答案:

答案 0 :(得分:3)

names[count] = str;为您的数组的每个成员分配str的地址。他们都指向。所以他们自然都指向"Haeltar",这是最后写入str的内容。请注意,在执行赋值时,您也会泄漏所有已分配的内存。

您需要将names定义为char names[100][50]并直接阅读fgets(names[count], 50, file)。或者为每个成员分配内存(使用malloc,就像你已经做过的那样)并复制到其中(使用strcpy 1

1 如果您有幸进入POSIX系统,strdup可以通过一次通话完成这两项工作。

答案 1 :(得分:2)

有几个错误:

首先,您必须将输入字符串复制到数组中,您只需替换最初来自malloc的指针。

strcpy(names[count], str);

接下来,您必须在使用之后递增count,而不是之前:您未使用元素0

第三,您在两个应该使用length的地方使用count - 实际的条目数,此处

qsort(names, count, sizeof(char*), compare);    // change length to count

在这里

for(int i = 0; i < count; i++) {                // change length to count

答案 2 :(得分:1)

你有2个明显的错误: 1)你过早增加count。名称数组中的第一个条目是未分配的,因为您尝试打印它可能会导致应用程序崩溃。

if (file) {
        while ((fgets(str, 50, file)) != NULL){
            names[count] = str;
            printf("%s", names[count]); //This will print names as read from file
            ++count;
        }      

2)您计算字符串,但使用length进行打印。将其更改为count,它会起作用。

for(int i = 0; i < count; ++i){
        printf("%s", names[i]);    
}