fgets() 在文件读取中获取的内容超出了应有的范围 - C
fgets() gets more than it should in file reading - C
目前我正在做一个拼贴的实际工作我必须从文件中读取数据。
文件数据结构为:"id name sex"
示例:
nm0025630 Vikas Anand M
nm0418131 Victor Janson M
nm0411451 Dick Israel M
nm0757820 Leopoldo Salcedo M
阅读当前我正在使用此代码:
fh = NULL;
fh = fopen(ACTORS, "r");
if (!fh) {
exit(1);
}
while (!feof(fh)) {
char sex, name[100], id[10];
fgets(id, 10, fh);
fgets(name, 100, fh);
fgetc(sex);
if (!feof(fh)) {
hash_update_node(hash, get_id_num(id), name, sex);
count++;
}
}
问题是它把姓名和性别一起读了。
感谢任何帮助。
fgets(name, 100, fh);
最多读取99个字符,当名字少于98个字符时,如果之前只有一个space,性别也会被读取。
因为名字可能由几个用 spaces 分隔的单词组成,一种方法是读取所有行然后提取性别。
警告你第一次这样做 while (!feof(fh)) {
这之前没有任何阅读所以 feof
不知道文件是否为空然后你是否到达 EOF。我鼓励您检测读取结果中的 EOF。
也因为你只保存读取的数据,if (!feof(fh)){
你没有记住最后一行的信息
另请注意fgets
如果有足够的地方可以保存换行符,使用fscanf
更实用。
所以一种方法可以是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define ACTORS "/tmp/actors"
int main()
{
FILE * fh = fopen(ACTORS, "r");
if (!fh) {
perror("cannot read " ACTORS);
exit(1);
}
char name[100],id[10];
while (fscanf(fh, "%9s %99[^\n]", id, name) == 2) {
size_t sz = strlen(name);
char sex = name[--sz];
for (;;) {
if (sz == 0) {
puts("empty name");
exit(2);
}
if (!isspace((unsigned char) name[--sz]))
break;
}
name[sz+1] = 0;
/*
hash_update_node(hash, get_id_num(id) , name, sex);
count++;
*/
printf("id='%s', name='%s', sex=%c\n", id, name, sex);
}
fclose(fh);
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall r.c
pi@raspberrypi:/tmp $ ./a.out
cannot read /tmp/actors: No such file or directory
pi@raspberrypi:/tmp $ cat > actors
nm0025630 Vikas Anand M
nm0418131 Victor Janson M
nm0411451 Dick Israel M
nm0757820 Leopoldo Salcedo M
pi@raspberrypi:/tmp $ ./a.out
id='nm0025630', name='Vikas Anand', sex=M
id='nm0418131', name='Victor Janson', sex=M
id='nm0411451', name='Dick Israel', sex=M
id='nm0757820', name='Leopoldo Salcedo', sex=M
pi@raspberrypi:/tmp $
文件中的字段似乎由 TAB 字符分隔。如果这是正确的,您可以使用 fscanf()
:
解析文件
#include <stdio.h>
#include <stdlib.h>
int local_file(void) {
char sex, name[100], id[10];
int count = 0;
FILE *fh = fopen(ACTORS, "r");
if (!fh) {
exit(1);
}
while (fscanf("%9[^\t]%*1[\t]%99[^\t]%*1[\t]%c", id, name, &sex) == 3) {
hash_update_node(hash, get_id_num(id), name, sex);
count++;
}
return count;
}
但是请注意,如果任何字段为空,此代码将失败。
目前我正在做一个拼贴的实际工作我必须从文件中读取数据。
文件数据结构为:"id name sex"
示例:
nm0025630 Vikas Anand M nm0418131 Victor Janson M nm0411451 Dick Israel M nm0757820 Leopoldo Salcedo M
阅读当前我正在使用此代码:
fh = NULL;
fh = fopen(ACTORS, "r");
if (!fh) {
exit(1);
}
while (!feof(fh)) {
char sex, name[100], id[10];
fgets(id, 10, fh);
fgets(name, 100, fh);
fgetc(sex);
if (!feof(fh)) {
hash_update_node(hash, get_id_num(id), name, sex);
count++;
}
}
问题是它把姓名和性别一起读了。 感谢任何帮助。
fgets(name, 100, fh);
最多读取99个字符,当名字少于98个字符时,如果之前只有一个space,性别也会被读取。
因为名字可能由几个用 spaces 分隔的单词组成,一种方法是读取所有行然后提取性别。
警告你第一次这样做 while (!feof(fh)) {
这之前没有任何阅读所以 feof
不知道文件是否为空然后你是否到达 EOF。我鼓励您检测读取结果中的 EOF。
也因为你只保存读取的数据,if (!feof(fh)){
你没有记住最后一行的信息
另请注意fgets
如果有足够的地方可以保存换行符,使用fscanf
更实用。
所以一种方法可以是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define ACTORS "/tmp/actors"
int main()
{
FILE * fh = fopen(ACTORS, "r");
if (!fh) {
perror("cannot read " ACTORS);
exit(1);
}
char name[100],id[10];
while (fscanf(fh, "%9s %99[^\n]", id, name) == 2) {
size_t sz = strlen(name);
char sex = name[--sz];
for (;;) {
if (sz == 0) {
puts("empty name");
exit(2);
}
if (!isspace((unsigned char) name[--sz]))
break;
}
name[sz+1] = 0;
/*
hash_update_node(hash, get_id_num(id) , name, sex);
count++;
*/
printf("id='%s', name='%s', sex=%c\n", id, name, sex);
}
fclose(fh);
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall r.c
pi@raspberrypi:/tmp $ ./a.out
cannot read /tmp/actors: No such file or directory
pi@raspberrypi:/tmp $ cat > actors
nm0025630 Vikas Anand M
nm0418131 Victor Janson M
nm0411451 Dick Israel M
nm0757820 Leopoldo Salcedo M
pi@raspberrypi:/tmp $ ./a.out
id='nm0025630', name='Vikas Anand', sex=M
id='nm0418131', name='Victor Janson', sex=M
id='nm0411451', name='Dick Israel', sex=M
id='nm0757820', name='Leopoldo Salcedo', sex=M
pi@raspberrypi:/tmp $
文件中的字段似乎由 TAB 字符分隔。如果这是正确的,您可以使用 fscanf()
:
#include <stdio.h>
#include <stdlib.h>
int local_file(void) {
char sex, name[100], id[10];
int count = 0;
FILE *fh = fopen(ACTORS, "r");
if (!fh) {
exit(1);
}
while (fscanf("%9[^\t]%*1[\t]%99[^\t]%*1[\t]%c", id, name, &sex) == 3) {
hash_update_node(hash, get_id_num(id), name, sex);
count++;
}
return count;
}
但是请注意,如果任何字段为空,此代码将失败。