我正在从文件到结构阅读并遇到问题。我有测试文件,其中第一个字母定义结构名称第二个数字告诉我它有多少个节点,其余的数字是节点。文件示例:
A 4 1 2 3 4
B 5 1 2 3 9 8
C 3 1 2 3
所以例如结构应该是这样的:name-> A; numberOfNodes-→4;节点 - > {1,2,3,4}。我保存每行的结构是:
struct mystruct{
char name[1];
int numberOfNodes;
int nodes[];
};
到目前为止我的功能:
lines = lineCount(courses); //calculates how many rows file has
struct courses course[lines];
co = fopen(courses, mode);
if(co == NULL){
printf("Can't find the files.");
exit(1);
}else{
for(i = 0; i < lines; i++){
fscanf(co, "%1s %d \n", ¤t, &id1); //Doesnt have any problems reading these two parameters;
for(j = 0 ; j < id1; j++){
fscanf(co, "%d", &course[i].nodes[j]); //Have no idea how to store array =/
}
strcpy(course[i].courseName, current);
course[i].numberOfNodes = id1;
}
}
编辑:我很抱歉让你们感到困惑,它只是很好地分配整数,但不输出相同的东西,它会输出这样的东西:
A 4 69 72 1 2
B 5 20 45 7 3 1
C 3 2 45 1
我认为这段代码没有做我想做的事情:
for(j = 0 ; j < id1; j++){
fscanf(co, "%d", &course[i].nodes[j]); //Have no idea how to store array =/
}
非常感谢任何帮助!
答案 0 :(得分:2)
您的代码不会为整数数组分配任何内存,int nodes[]
被称为灵活数组成员它有它的用途而且它不是保留任何内存,你需要为nodes
数组分配动态内存:
struct mystruct {
char name[1];
int numberOfNodes;
int *nodes;
};
...
fscanf(co, "%c %d \n", ¤t, &id1);
course[i].nodes = malloc(sizeof(int)*id1);
请注意,%1s
格式说明符扫描1个字符的字符串,之后会添加一个空终止字节,因此您应该使用%c
来只读一个字符。
注1:完成后不要忘记free()
已分配的所有内存,例如
free(course[i].nodes);
注2:在C中分配内存的惯用方法是:
malloc(num_of_elements * sizeof *ptr_to_type);
我没有在此处介绍以避免混淆,同时请注意我个人不喜欢投射malloc()
的结果,这有一些很好的理由:
Do I cast the result of malloc?
答案 1 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
struct mystruct {
struct mystruct *next;
char name; /* No need to dim array as name[1] */
int numberOfNodes;
int nodes[];
};
int main(void)
{
/* Don't like VLA's, I used a list */
struct mystruct *curr, *first = NULL, *prior = NULL;
char s[256], *p;
FILE *f;
int i;
/* Open (No need to count lines before) */
f = fopen("data", "r");
if (f == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
/* Fill */
while (fgets(s, sizeof(s), f) != NULL) {
i = (int)strtol(&s[1], &p, 10);
if (i == 0) continue; /* Skip blank or 0 node */
/* Flexible array must be alloced with parent */
curr = malloc((sizeof *curr) + (sizeof(int) * (size_t)i));
curr->next = NULL;
curr->name = s[0];
curr->numberOfNodes = i;
for (i = 0; i < curr->numberOfNodes; i++) {
curr->nodes[i] = (int)strtol(p, &p, 10);
}
if (prior) {
prior->next = curr;
} else {
first = curr;
}
prior = curr;
}
fclose(f);
/* Print */
curr = first;
while (curr) {
printf("%c %d", curr->name, curr->numberOfNodes);
for (i = 0; i < curr->numberOfNodes; i++) {
printf(" %d", curr->nodes[i]);
}
printf("\n");
curr = curr->next;
}
/* Free */
while (first) {
curr = first->next;
free(first);
first = curr;
}
return 0;
}
答案 2 :(得分:0)
你的问题是你之前不知道有多少数字跟着这封信。 所以你可以说不超过1000或任何你发现“足够”的东西。或者您将此数字一个接一个地存储在一种链接结构中。如果你使用提供链表的例如库,那么后来要容易得多。其中一个例子就是油嘴滑舌。
如果要存储在数组中,则必须使用填充动态为数组分配空间。你需要一些malloc / realloc / free的组合。
存储数组的iteme可以在打印时完成 &amp; course [i] .nodes [j]会做,但当然你需要足够的空间来真正访问节点[j]
此致
答案 3 :(得分:-1)
如果您使用的是标准C / C ++,则需要在分配值之前初始化数组,并确保在fscanf()时获得正确的指针!
struct mystruct{
char name[1];
int numberOfNodes;
int* nodes;
};
然后在你的if:
的else部分else{
for(i = 0; i < lines; i++){
fscanf(co, "%1s %d \n", ¤t, &id1); //Doesnt have any problems reading these two parameters;
course[i].nodes = new int[id1]; //init array length of id1 value
for(j = 0 ; j < id1; j++){
int tempNode;
fscanf(co, "%d", &tempNode);
course[i].nodes[j] = tempNode; //allocate the node value to the correct location.
}
strcpy(course[i].courseName, current);
course[i].numberOfNodes = id1;
}
或者,您应该可以使用以下方法绕过临时值:
fscanf(co, "%d", &(course[i].nodes[j]));
但我认为有些编译器可能无法认为这是正确的。由于您的数据结构,使用临时值更好 - 我的意见。
最后不要忘记遍历course []向量和delete (course[i].nodes)
如果你想要纯C,你将需要使用malloc()这可能很难处理 - 好不像新的那样漂亮,删除。
无论如何,我建议使用STL向量进行更简单的内存管理,减轻指针分配的压力,并使用预定义的运算符函数 - push_back,pop_back,insert,使用优雅的数据管理(迭代,添加,删除),擦除。
http://www.cplusplus.com/reference/vector/vector/
我在某些代码中加了'()'来强调运算符的优先级。