arrays - 将文件逐行读入C中的字符串数组
问题描述
我正在尝试将以下文件逐行读取到字符串数组中,其中每一行都是数组的一个元素:
AATGC
ATGCC
GCCGT
CGTAC
GTACG
TACGT
ACGTA
CGTAC
GTACG
TACGA
ACGAA
我的代码如下:
void **get_genome(char *filename) {
FILE *file = fopen(filename, "r");
int c;
int line_count = 0;
int line_length = 0;
for (c = getc(file); c != EOF; c = getc(file)) {
if (c == '\n') line_count++;
else line_length++;
}
line_length /= line_count;
rewind(file);
char **genome = calloc(line_length * line_count, sizeof(char));
for (int i = 0; i < line_count; i++) {
genome[i] = calloc(line_length, sizeof(char));
fscanf(file, "%s\n", genome[i]);
}
printf("%d lines of %d length\n", line_count, line_length);
for (int i = 0; i < line_count; i++)
printf("%s\n", genome[i]);
}
但是,由于某种原因,我得到了数组前 2 个元素的垃圾输出。以下是我的输出:
`NP��
�NP��
GCCGT
CGTAC
GTACG
TACGT
ACGTA
CGTAC
GTACG
TACGA
ACGAA
解决方案
您似乎假设所有行都具有相同的行长。如果是这样的话,你仍然有一些问题:
行指针的内存分配不正确,应该是
char **genome = calloc(line_count, sizeof(char *));
或者更好,更不容易出错:
char **genome = calloc(line_count, sizeof(*genome));
每行的内存应该比空终止符长一个字节。
\n
是fscanf()
格式字符串匹配任何空白字符序列。%s
无论如何跳过这些都是多余的。如果文件包含任何空白字符,则对以空格分隔的项目进行计数会更安全,以避免对项目进行错误计数。
你不关闭
file
。你不要
genome
在函数的末尾返回你不检查错误。
这是修改后的版本:
void **get_genome(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL)
return NULL;
int line_count = 1;
int item_count = 0;
int item_length = -1;
int length = 0;
int c;
while ((c = getc(file)) != EOF) {
if (isspace(c)) {
if (length == 0)
continue; // ignore subsequent whitespace
item_count++;
if (item_length < 0) {
item_length = length;
} else
if (item_length != length) {
printf("inconsistent item length on line %d\", line_count);
fclose(file);
return NULL;
}
length = 0;
} else {
length++;
}
}
if (length) {
printf("line %d truncated\n", line_count);
fclose(file);
return NULL;
}
rewind(file);
char **genome = calloc(item_count, sizeof(*genome));
if (genome == NULL) {
printf("out of memory\n");
fclose(file);
return NULL;
}
for (int i = 0; i < item_count; i++) {
genome[i] = calloc(item_length + 1, sizeof(*genome[i]));
if (genome[i] == NULL) {
while (i > 0) {
free(genome[i]);
}
free(genome);
printf("out of memory\n");
fclose(file);
return NULL;
}
fscanf(file, "%s", genome[i]);
}
fclose(file);
printf("%d items of %d length on %d lines\n",
item_count, item_length, line_count);
for (int i = 0; i < item_count; i++)
printf("%s\n", genome[i]);
return genome;
}
推荐阅读
- rx-java - 使用 rxjava 防止多次调用该方法
- c++ - 如何管理许多 char 数组变量?
- x86 - 分支预测和推测性提取缓解
- postgresql - 使用 SymmetricDS 同步无效的 Postgis 几何
- c - 为什么我不能将指向结构的指针保存到指向指针数组的指针的索引?
- eclipse - Git commit 显示已更改的文件,如元数据,尽管它们位于 gitignore 文件中
- haskell - GHC,简单性能测试产生疯狂的锯齿图
- .net-core - MVC 属性路由在 .net Core 中找不到链接
- haskell - Haskell以特定顺序加入列表中的函数输入
- java - Maven 万无一失和模块化 JavaFX 11