0

我想从具有字符串 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) 提供奇怪的符号,并在因分段错误而崩溃之前为整数提供不正确的数字。我很难追查原因。

4

5 回答 5

4

您的fscanf调用正在写入未初始化的指针。这会调用未定义的行为,并且它不会崩溃有点令人惊讶。

您需要为字符串分配存储空间

char tempName[30];

并且还应该修改您的fscanf调用以最多读取这么多字符并检查是否读取了所有 3 个名称、位置、方法

while (fscanf(f, "%29s %d %d", tempName, &tempLoc, &tempNum) == 3)

正如 Marcus 所指出的,您还需要为classNamein分配存储空间LinkedListNode。最简单的方法是制作className一个 30 元素char数组并使用strcpy

strcpy(newNode->className, inName);

或者您也可以className作为 a离开char*并动态分配其内存

newNode->className = malloc(strlen(inName)+1);
/* check for newNode->className != NULL */
strcpy(newNode->className, inName);

如果这样做,请确保在释放className节点时释放。

于 2013-05-17T07:53:14.390 回答
1
char* tempName;

不指向内存区域。并且您已在 fscanf 中使用而未将其分配给内存:

您可以通过更改 tempname 声明来解决此问题:

char tempName[MAX_NAME_SIZE];

或者您可以保留声明并使用"%ms"而不是"%s"fscanf 中的格式字符串说明符

fscanf(f, "%ms %d %d", &tempName, &tempLoc, &tempNum)

%ms将允许 fscanf 为 tempName 分配内存。free()当您的内存变得无用时,您必须释放此内存

%ms如果 gcc 版本为 >,则注释有效gcc 2.7

于 2013-05-17T07:53:21.933 回答
0

你还需要深拷贝inName;你所做的一切

newNode->className = inName

正在复制指针,而不是实际的字符串数据。你可以使用 strcpy 来做到这一点。

于 2013-05-17T07:53:28.467 回答
0

字符*临时名称;

tempName 指向随机内存。所以为 tempName 分配内存。

fscanf 的返回值:成功时,函数返回参数列表中成功填充的项目数。由于匹配失败、读取错误或到达文件结尾,此计数可以与预期的项目数匹配或更少(甚至为零)。

于 2013-05-17T08:08:36.540 回答
0

此外,当从文件读取数据完成时,您应该将 null 存储在最后一个链表中。

于 2013-05-17T08:13:11.043 回答