C中的fscanf,文本文件没有空格

时间:2014-10-22 08:30:25

标签: c scanf

我有一个文本文件,其名称如下所示:

" MARY"" PATRICIA"" LINDA"" BARBARA"" ELIZABETH"&# 34; JENNIFER"" MARIA"" SUSAN""霭",

我使用以下代码尝试将名称放入数组中:

char * names[9];
int i = 0;
FILE * fp = fopen("names.txt", "r");

for (i=0; i < 9; i++) {
  fscanf(fp, "\"%s\",", names[i]);
}

当我尝试运行它时,程序会出现分段错误。我仔细调试了,我注意到当我尝试读取第二个名字时出现了错误。

有人知道为什么我的代码不起作用,还有为什么会发生分段错误?

3 个答案:

答案 0 :(得分:3)

您的代码中有undefined behavior,因为您没有为fscanf来电中写入的指针分配内存。

你有一个包含9个未初始化指针的数组,因为它们是局部变量的一部分,所以它们具有不确定的值,即它们将指向看似随机的位置。写入内存中的随机位置(当你调用fscanf时会发生这种情况)会做坏事。

解决问题的最简单方法是使用数组数组,例如

char names[9][20];

这将为您提供一个包含九个数组的数组,每个子数组为20个字符(允许您使用最多19个字符的名称)。

为了不写出界限,您还应修改您的通话,以便您不会读取多个字符:

fscanf(fp, "\"%19s\",", names[i]);

然而,使用fscanf函数存在另一个问题,那就是读取字符串"%s"的格式会一直读取,直到它在输入中找到空格(或直到如果提供了字段宽度,则达到限制。)

简而言之:您无法使用fscanf来阅读您的输入。

相反,我建议您使用fgets一次将整行读入内存,然后使用例如将逗号分隔为逗号。 strtok


将任意长行作为文件输入处理的一种方法(伪代码):

#define SIZE 256

size_t current_size = SIZE;
char *buffer = malloc(current_size);
buffer[0] = '\0';  // Terminator at first character, makes the string empty

for (;;)
{
    // Read into temporary buffer
    char temp[SIZE];
    fgets(temp, sizeof(temp), file_pointer);

    // Append to actual buffer
    strcat(buffer, temp);

    // If last character is a newline (which `fgets` always append
    // if it reaches the end of the line) then the whole line have
    // been read and we are done
    if (last_character_is_newline(buffer))
        break;

    // Still more data to read from the line
    // Allocate a larger buffer
    current_size += SIZE;
    buffer = realloc(buffer, current_size);

    // Continues the loop to try and read the next part of the line
}

// After the loop the pointer `buffer` points to memory containing the whole line

[ 注意: 上面的代码段不包含任何错误处理。]

答案 1 :(得分:1)

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

int main(void) {
    char *names[9], buff[32];
    int i = 0;
    FILE *fp = fopen("names.txt", "r");

    for(i = 0; i < 9; i++) {
        if(1==fscanf(fp, "\"%31[^\"]\",", buff)){//"\"%s\"," does not work like that what you want
            size_t len = strlen(buff) + 1;
            names[i] = malloc(len);//Space is required to load the strings of each
            memcpy(names[i], buff, len);
        }
    }
    fclose(fp);
    //check print & deallocate
    for(i = 0; i< 9; ++i){
        puts(names[i]);
        free(names[i]);
    }
    return 0;
}

答案 2 :(得分:0)

试试这个......

for (i=0; i < 9; i++) 
{
   names[i]=malloc(15);// you should take care about size
   fscanf(fp, "\"%s\",", names[i]);
}