在C中使用fgets()和strtok()逐行读取文件?
我试图使用fgets和strtok()逐行读取文件,并创建每行不同信息的链接列表 现在,我只是将信息放入一个数组,只是想弄清楚如何正确地读取信息,但它不能正常工作 在while(fgets)部分,它似乎正确地将所有内容加载到数组中,并将其打印出来。然而,在执行了该循环并尝试打印出整个数组之后,我得到了非常奇怪的结果。。大部分是最后一行的一部分,大部分不是完整的单词或任何东西 例如,如果我正在阅读:在C中使用fgets()和strtok()逐行读取文件?,c,fgets,strtok,C,Fgets,Strtok,我试图使用fgets和strtok()逐行读取文件,并创建每行不同信息的链接列表 现在,我只是将信息放入一个数组,只是想弄清楚如何正确地读取信息,但它不能正常工作 在while(fgets)部分,它似乎正确地将所有内容加载到数组中,并将其打印出来。然而,在执行了该循环并尝试打印出整个数组之后,我得到了非常奇怪的结果。。大部分是最后一行的一部分,大部分不是完整的单词或任何东西 例如,如果我正在阅读: Simpson, Homer, Male, 1976 Simpson, Marge, Female
Simpson, Homer, Male, 1976
Simpson, Marge, Female, 1978
Simpson, Bart, Male, 2002
Simpson, Lisa, Female, 2004
Simpson, Maggie, Female, 2011
我最后得到的打印输出类似于:
le
Simpson
Maggie
Simpson
Maggie
e
ale
Simpson
Maggie
e
e
Simpson
Maggie
Female
2011
请告诉我哪里出了问题,谢谢
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRINGSIZE 10
#define LINESIZE 128
struct person{
char firstName[MAXSTRINGSIZE];
char lastName[MAXSTRINGSIZE];
char gender[MAXSTRINGSIZE];
int birthYear;
struct person *next;
} *first, *current;
int main (void){
static const char filename[] = "Assignment1file.txt";
FILE *myfile = fopen ( "Assignment1file.txt", "r" );
int i=0;
int j=0;
int k=0;
int l=0;
char *result[10][4];
char line[LINESIZE];
char *value;
for(i=0; i<9; i++){
for(j=0;j<4;j++){
result[i][j] = NULL;
}
}
i=0;
// loop through each entry in Assignment1file
while(fgets(line, sizeof(line), myfile)){
//load last name
value = strtok(line, ",");
result[i][0] = value;
printf("%i 0 %s", i, value);
//load first time
value = strtok(NULL, ",");
result[i][1] = value;
printf("%i 1 %s", i, value);
// load gender
value = strtok(NULL, ",");
result[i][2] = value;
printf("%i 2 %s", i, value);
// load birth year
value = strtok(NULL, "\n");
result[i][3] = value;
printf("%i 3 %s", i, value);
printf("\n");
for(j=0;j<4;j++){
printf("%s\n", result[i][j]);
}
//go to next line
i++;
}
// read out the array
for(k=0; k<5; k++){
for(j=0;j<4;j++){
printf("%s\n", result[k][j]);
}
}
fclose(myfile);
return 0;
}
#包括
#包括
#包括
#定义MAXSTRINGSIZE 10
#定义线宽128
结构人{
char firstName[MAXSTRINGSIZE];
char lastName[MAXSTRINGSIZE];
字符性别[MAXSTRINGSIZE];
int生日;
结构人*next;
}*第一,*当前;
内部主(空){
静态常量字符文件名[]=“Assignment1file.txt”;
FILE*myfile=fopen(“Assignment1file.txt”、“r”);
int i=0;
int j=0;
int k=0;
int l=0;
字符*结果[10][4];
字符行[行大小];
字符*值;
对于(i=0;i,如果需要,您需要将令牌复制到单独的存储器中
strtok()
将修改读取行的缓冲区,用NUL字符替换分隔符,并返回指向缓冲区中特定位置的指针(即当前标记的开始)
当您读入下一行时,缓冲区将被新数据填充,因此,您保存的所有指针都是无用的,因为以前的数据现在已经不存在了
引自:
要确定令牌的开始和结束,函数首先从起始位置扫描分隔符中包含的第一个字符而不是(它将成为令牌的开始)。然后从标记的此开头开始扫描分隔符中包含的第一个字符,该字符将成为标记的结尾
函数会自动将令牌的这一端替换为空字符,函数会返回令牌的开头
和(我的重点):
str
要截断的C字符串。此字符串的内容将被修改并分成更小的字符串(标记)。
或者,可以指定一个空指针,在这种情况下,函数继续扫描先前对函数的成功调用结束的位置
分隔符:
包含分隔符的C字符串。
这些可能因电话而异
strtok
将修改原始字符串。因此,在每次迭代后,存储的以前的指针不再存在
简单的解决方案是使用:分配和复制值
只需在任何地方修改值的赋值即可:
result[i][0] = value;
致:
strtok()
返回行[]内的指针
因此,当您阅读下一行时,您保存的所有指针现在都指向存储文件最后一行的位置
您可以为字符串的每一位分配内存,如下所示:
//load last name
value = strtok(line, ",");
result[i][0] = malloc(strlen(value) + 1);
strcpy(result[i][0], value);
另外,您不需要在开始时使用循环将所有内容设置为NULL
,您可以这样做:
char *result[10][4] = {0};
这段代码有几个问题。我已经很快修改了你的代码以达到预期效果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRINGSIZE 10
#define LINESIZE 128
struct person{
char firstName[MAXSTRINGSIZE];
char lastName[MAXSTRINGSIZE];
char gender[MAXSTRINGSIZE];
int birthYear;
struct person *next;
} *first, *current;
int main (void){
FILE *myfile = fopen ( "Assignment1file.txt", "r" );
int i=0;
int j=0;
int k=0;
int l=0;
char *result[10][4];
char line[LINESIZE];
char *value;
for(i=0; i<=9; i++){
for(j=0;j<=4;j++){
result[i][j] = NULL;
}
}
i=0;
// loop through each entry in Assignment1file
while(fgets(line, sizeof(line), myfile)){
//load last name
value = strtok(line, ", ");
result[i][0] = strdup(value);
printf("last: %s\n", value);
//load first time
value = strtok(NULL, ", ");
result[i][1] = strdup(value);
printf("first: %s\n", value);
// load gender
value = strtok(NULL, ", ");
result[i][2] = strdup(value);
printf("gender: %s\n", value);
// load birth year
value = strtok(NULL, " \n");
result[i][3] = strdup(value);
printf("birth year: %s\n", value);
//go to next line
i++;
}
// read out the array
for(k=0; k<5; k++){
for(j=0;j<4;j++){
printf("%s\n", result[k][j]);
}
}
fclose(myfile);
return 0;
}
#包括
#包括
#包括
#定义MAXSTRINGSIZE 10
#定义线宽128
结构人{
char firstName[MAXSTRINGSIZE];
char lastName[MAXSTRINGSIZE];
字符性别[MAXSTRINGSIZE];
int生日;
结构人*next;
}*第一,*当前;
内部主(空){
FILE*myfile=fopen(“Assignment1file.txt”、“r”);
int i=0;
int j=0;
int k=0;
int l=0;
字符*结果[10][4];
字符行[行大小];
字符*值;
for(i=0;istrtok将返回指向原始字符串部分的指针。调用strtok时,原始字符串将被修改。strdup不是标准的C函数。可以实现,但是:如果删除了其他答案,这不一定有用。您介意添加一些详细信息吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRINGSIZE 10
#define LINESIZE 128
struct person{
char firstName[MAXSTRINGSIZE];
char lastName[MAXSTRINGSIZE];
char gender[MAXSTRINGSIZE];
int birthYear;
struct person *next;
} *first, *current;
int main (void){
FILE *myfile = fopen ( "Assignment1file.txt", "r" );
int i=0;
int j=0;
int k=0;
int l=0;
char *result[10][4];
char line[LINESIZE];
char *value;
for(i=0; i<=9; i++){
for(j=0;j<=4;j++){
result[i][j] = NULL;
}
}
i=0;
// loop through each entry in Assignment1file
while(fgets(line, sizeof(line), myfile)){
//load last name
value = strtok(line, ", ");
result[i][0] = strdup(value);
printf("last: %s\n", value);
//load first time
value = strtok(NULL, ", ");
result[i][1] = strdup(value);
printf("first: %s\n", value);
// load gender
value = strtok(NULL, ", ");
result[i][2] = strdup(value);
printf("gender: %s\n", value);
// load birth year
value = strtok(NULL, " \n");
result[i][3] = strdup(value);
printf("birth year: %s\n", value);
//go to next line
i++;
}
// read out the array
for(k=0; k<5; k++){
for(j=0;j<4;j++){
printf("%s\n", result[k][j]);
}
}
fclose(myfile);
return 0;
}