我有一个文本文件,其名称如下所示:
" 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]);
}
当我尝试运行它时,程序会出现分段错误。我仔细调试了,我注意到当我尝试读取第二个名字时出现了错误。
有人知道为什么我的代码不起作用,还有为什么会发生分段错误?
答案 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]);
}