仅存储c中LAST项的字符串数组



我正在尝试编写一个程序,其中我从文件中读取信息,并根据用户选择的不同列对其进行排序。我不关心排序在这个时刻,我只是似乎不能正确地存储数据,我只是得到最后一组项目从文件当我试图读到这个数组。问题是,我需要这些信息以特定的顺序排列,以便稍后对它们进行排序。在我的实际代码中,我将使用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"

最新更新