我正在尝试编写一个程序,其中我从文件中读取信息,并根据用户选择的不同列对其进行排序。我不关心排序在这个时刻,我只是似乎不能正确地存储数据,我只是得到最后一组项目从文件当我试图读到这个数组。问题是,我需要这些信息以特定的顺序排列,以便稍后对它们进行排序。在我的实际代码中,我将使用146行和4列,并对不同的列进行排序。
我不能在这个项目中使用动态内存分配
这是我想做的一个简单的例子,但这不是我的实际代码:
#include <stdio.h>
int main() {
char *array[2][3]; // Array to store the stuff, like a dataframe??
int i;
char name[10]; // Over-writable array to store name
char age[3]; //Over-writable array to store age
char occupation[12]; // Over writable for occupation
for(i=0; i < 2; i++)
{
scanf("%s %s %s", name, age, occupation); // Get name, age, and occupation as input from file
array[i][0] = name; // assign name to row position i, and column position 0
array[i][1] = age; // assign age to row position i, and column position 1
array[i][2] = occupation; // assign age to row position i, and column 2
// i becomes one after this to move to row 1, column assignments
// should stay the same
}
printf("%-20s %-20s %-20sn", "Name", "Age", "Occupation"); //Print column headers
for(i = 0; i < 2; i++)
{
printf("%-20s %-20s %-20sn", array[i][0], array[i][1], array[i][2]); //Print corresponding info
}
return 0;
}
那么让我们运行这个,我手动输入:
Steve 50 Retired
Alex 23 Server
我的输出如下所示:
Name Age Occupation
Alex 23 Server
Alex 23 Server
我需要将信息存储在临时数组中的原因是,在某些情况下,我只需要某些信息,而可以省略其他信息。例如,我可能需要生成一个按名称排序的文本文件,其中包括职业,但不包括年龄,在这种情况下,我只需要一个包含姓名和年龄的数组。
无论我做什么,我只得到任何给定数据列表的最后一个元素。这可能是一个200行4列的数组,我只会从我正在读取的任何文件中获得最后一个条目,并且它们都将以正确的格式打印,只使用给定的最后一块信息。
我可能也用了完全错误的方式,如果你有任何想法,请告诉我。
我对C中数组的了解可能会让我失败,我很难掌握指针与数组的关系,但我找不到一个大规模的2D例子来帮助我完成这个。
虽然strdup
当然是一个选项,但它使用动态内存分配(不要忘记释放它),您说您不能使用。
这里的建议是创建您自己的类型,以有组织的方式存储您收集的所有信息,为此您可以使用struct
。
这使得排序过程更容易,因为您可以轻松地使用qsort
和自定义比较器函数以任何方式对数组进行排序,而不会有太多麻烦。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char name[10];
char age[3];
char occupation[12];
}Info;
// comparator function example, sorts by alphabetical order of name
int compare(const void* a, const void* b)
{
return strcmp(((Info*)a)->name, ((Info*)b)->name);
}
int main()
{
Info array[3];
Info temp; // temporary variable you said you need
for (int i = 0; i < 3; i++)
{
// parse into temporary variable
if(scanf("%9s %2s %11s", temp.name, temp.age, temp.occupation) == 3)
{
// if all goes well assign it to the data container
array[i] = temp;
}
}
qsort(array, 3, sizeof *array, compare); // sorting the array
printf("%-20s %-20s %-20sn", "Name", "Age", "Occupation"); //Print column headers
for (int i = 0; i < 3; i++)
{
printf("%-20s %-20s %-20sn", array[i].name, array[i].age, array[i].occupation);
}
}
请注意,我还为您的scanf
添加了宽度限制,以避免缓冲区溢出,我还检查了它的返回值,这些都是应该为更健壮的代码做的事情。
在我看来,一个更好的选择是使用fgets
读取输入/文件和sscanf
来解析值。
richard 23 engineer
albert 45 driver
charles 24 lawyer
输出:
Name Age Occupation
albert 45 driver
charles 24 lawyer
richard 23 engineer
按名称按字母顺序排序。
你没有为你从scanf得到的这些char*分配任何内存,您可以直接使用mmalloc和strcpy,或者您也可以使用strdup同时执行这两个操作。
由于每次基本上都是从name/age/occupation中复制指针,因此最终得到相同的值,因为它们包含最后一次scanf调用的结果。
你正在做的事情的简单情况:
char* strarray[2];
char* str ="hello";
strarray[0]=str;
strarray[1]=str;
两个数组元素包含相同的指针那么现在如果我改变STR:
str ="Not Hello";
两个数组元素仍然指向相同的指针,因此将包含相同的字符串"Not Hello"