无法从C中的文本文件中读取所有名称

时间:2015-05-11 03:01:16

标签: c file stream segmentation-fault

我正在编写一个从文件中读取名称的程序。如果没有Segmentation Faulting,我无法阅读所有名称。这是我的代码。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

typedef struct node{
        char *name;
        int index;
}node;

int main(void){
        char *someString;
        struct node *TEST;

        TEST = (node*)malloc(sizeof(node));

        FILE *filePointer;
        filePointer = fopen("data2.txt","r");

        int lineCount = 0;
        //while(fscanf(filePointer, "%s", &someString) != EOF){
        while(1){
                if (!feof(filePointer)){
                        fscanf(filePointer, "%s", &someString);
                        printf("String from file: %s\n", &someString);                 
                }
                else{
                        break;         
                }
        }
}

2 个答案:

答案 0 :(得分:1)

您在此代码中的两个位置使用&somePointer都是错误的。 &somePointer的结果是char**。在应用一元地址运算符&时,结果是指向类型的指针。由于somePointerchar*,这意味着&somePointerchar**,而不是您想要的。 %s格式说明符使用scanf并且printf同样错误使用。

这两个函数都需要char缓冲区的地址,而不是char指针的地址。虽然您可能认为只使用somePointer会起作用,但实际上它不会,因为即使那时该变量也是不确定。您永远不会为指针提供char缓冲区所在的有效地址。

而且,你的while循环逻辑是错误的。它等同于while(!feof(filePointer))循环,几乎总是错误的。您可以阅读更多相关信息here

以下是一个简单的代码块,可以安全地从文件中读取最多127个字符的字符串,直到文件耗尽或遇到错误:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buff[128];

    FILE *fp = fopen("data2.txt","r");
    if (fp == NULL)
    {
        perror("data2.txt");
        return EXIT_FAILURE;
    }

    while (fscanf(fp, "%127s", buff) == 1)
    {
        printf("String from file: %s\n", buff);
    }

    fclose(fp);

    return 0;
}

添加指向此指针会略微修改:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buff[128];
    char *somePointer = buff;

    FILE *fp = fopen("data2.txt","r");
    if (fp == NULL)
    {
        perror("data2.txt");
        return EXIT_FAILURE;
    }

    while (fscanf(fp, "%127s", somePointer) == 1)
    {
        printf("String from file: %s\n", somePointer);
    }

    fclose(fp);

    return 0;
}

接下来,动态分配而不是固定的自动缓冲区。这给了我们:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *somePointer = malloc(128);
    if (somePointer == NULL)
    {
        perror("Failed to allocate buffer space");
        return EXIT_FAILURE;
    }

    FILE *fp = fopen("data2.txt","r");
    if (fp == NULL)
    {
        perror("data2.txt");
        return EXIT_FAILURE;
    }

    while (fscanf(fp, "%127s", somePointer) == 1)
    {
        printf("String from file: %s\n", somePointer);
    }

    fclose(fp);

    free(somePointer);

    return 0;
}

在上面的每种情况下,传递给fscanfprintf的参数最终都是指向char的指针。第一个是通过转换完成的,后两个是明确的。以下哪项适用于您的使用需求,我留给您。

其余的我留给你。祝你好运!

答案 1 :(得分:0)

你是段错误,因为你从未真正分配一个地方来存储字符串。 “someString”和node-&gt; name都是字符指针,但它们指向什么?当你运行malloc时,你正在分配一个包含指针的结构,但同样,它指的是什么?

你真正需要的是声明一个放置字符串的地方,如下所示:

    #define MAX_STRING_SIZE 50
    char thisIsTheActualString[MAX_STRING_SIZE];
    char *someString = thisIsTheActualString;

最后一行(我们分配给someString的地方)是完全冗余的,我将它留在显示你声明的指针和持有字符串的实际分配内存之间的关系。

如果你不这样做,那么当你到达while循环中的fscanf语句时,你会指示编译器将数据存储在someString中包含的地址...我们从未实际分配给任何东西。结果,你正在写一些随机存储器地址,这是你得到段错误的地方。