我想从具有字符串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( 以及在因分割错误而崩溃之前int的错误数字。我很难找到原因。
您的fscanf
调用正在写入一个未初始化的指针。这会调用未定义的行为,而且它不会崩溃有点令人惊讶。
您需要为字符串分配存储空间
char tempName[30];
还应该修改你的fscanf
调用,使其最多读取这么多个字符,并检查名称、位置和方法中的所有3个都已读取
while (fscanf(f, "%29s %d %d", tempName, &tempLoc, &tempNum) == 3)
正如Marcus所指出的,您还需要在LinkedListNode
中为className
分配存储。最简单的方法是使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
。
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版本>gcc 2.7
%ms
有效您还需要深度复制inName;你在中所做的一切
newNode->className = inName
正在复制指针,而不是实际的字符串数据。您可以使用strcpy来完成此操作。
char*tempName;
tempName指向随机内存。因此,为tempName分配内存。
fscanf的返回值:成功时,函数返回成功填充的参数列表的项数。此计数可能与预期的项数匹配,也可能由于匹配失败、读取错误或到达文件末尾而减少(甚至为零(。
此外,当从文件读取数据完成时,您应该将null存储在最后一个链表中。