我想从具有字符串int int格式的文本文件中读取值,如下所示:
testing 5 17
charlie 12 1
delta 88 4
我有一个使用fscanf读取文件的函数,将输入放入一些变量然后将它们发送到一个函数,将它们作为链表节点插入:
void readFile(LinkedList *inList, char* file)
{
char* tempName;
int tempLoc, tempNum;
FILE* f;
f = fopen(file, "r");
if(f==NULL)
{
printf("Error: could not open file");
}
else
{
while (fscanf(f, "%s %d %d", tempName, &tempLoc, &tempNum) != EOF)
{
insertFirst (inList, tempName, tempLoc, tempNum);
}
}
}
insertFirst函数:
void insertFirst(LinkedList* list, char* inName, int inLoc, int inNumMeth)
{
LinkedListNode* newNode;
newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode));
newNode->className = inName;
newNode->loc = inLoc;
newNode->numMethods;
newNode->next = list->head;
list->head = newNode;
}
当我遍历链表以打印出值时,它会在出现分段错误之前为名称( t)和整数的错误数字提供奇怪的符号。我无法追查原因。
答案 0 :(得分:4)
您的fscanf
来电正在写入未初始化的指针。这会调用未定义的行为,它有点令人惊讶,它不会崩溃。
您需要为字符串
分配存储空间char tempName[30];
并且还应该修改您的fscanf
调用以最多阅读这么多字符并检查所有3个名称,位置和方法是否已被阅读
while (fscanf(f, "%29s %d %d", tempName, &tempLoc, &tempNum) == 3)
如Marcus所述,您还需要为className
中的LinkedListNode
分配存储空间。最简单的方法是将className
设为30个元素char
数组并使用strcpy
strcpy(newNode->className, inName);
或者您也可以将className
作为char*
并动态分配其内存
newNode->className = malloc(strlen(inName)+1);
/* check for newNode->className != NULL */
strcpy(newNode->className, inName);
如果您这样做,请确保在释放节点时释放className
。
答案 1 :(得分:1)
char* tempName;
未指向内存区域。并且您已经在fscanf中使用而未将其分配给内存:
您可以通过更改tempname声明来解决此问题:
char tempName[MAX_NAME_SIZE];
或者你可以保留声明,并在fscanf的格式字符串说明符中使用"%ms"
而不是"%s"
fscanf(f, "%ms %d %d", &tempName, &tempLoc, &tempNum)
%ms
将允许fscanf为tempName分配内存。当你的记忆无用时,你必须用free()
释放这段记忆
如果gcc版本为>则注意%ms
有效gcc 2.7
答案 2 :(得分:0)
您还需要深入复制inName;你正在做的所有事情
newNode->className = inName
正在复制指针,而不是实际的字符串数据。你可以使用strcpy来做到这一点。
答案 3 :(得分:0)
char * tempName;
tempName指向随机内存。为tempName分配内存。
fscanf的返回值: 成功时,该函数返回成功填充的参数列表的项数。由于匹配失败,读取错误或文件结束的范围,此计数可以匹配预期的项目数或更少(甚至为零)。
答案 4 :(得分:0)
此外,您应该在最后一个链接列表中存储null,因为从文件读取的数据已完成。