如何扫描txt文件中的数据并存储在C中的数组中?
How to scan txt file for data and store in arrays in C?
我正在尝试读取包含字符串和数字的文本文件并保存到它们各自的数组中。这是我正在尝试读取的内容文本文件
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
我需要在并行数组中保存 repescitve 人的姓氏、名字和年龄。 (所以我需要在阅读时丢弃逗号)。
这是我目前所拥有的。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char line[100][41];
char junk[100];
int i;
FILE *file = fopen(argv[1], "r");
if(!file) {
printf("Could not open file. Exiting application.");
return 1;
}
for(i=0; i<100; i++)
{
fscanf(file, "%[^\n]", line[i]); //Get text
fscanf(file,"%[ \n\t\r]s",junk); //Remove any 'white space' characters
}
fclose(file);
for (i=0; i<30; i++)
printf("%s\n",line[i]);
return 0;
}
我已经在 IDE 中传递了文件参数。我在输出末尾得到了很多特殊字符。
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
┌
t╠╠
$
M
v
9 Rì
xá
╚
±
t/╗₧8
¿≡`
Tq töq t4≤`
ÿv
h(((( Hääääääääääüüüüüüéééééé
为什么我要读那些特殊字符?以及如何丢弃逗号并保存到三个不同的数组中?
你不看那些特殊字符。它们恰好存在于你的数组中,因为它是一个非静态持续时间的未初始化数组。因此,当您到达文件末尾时,因为您没有测试输入函数的结果,所以您将垃圾留在缓冲区中,稍后打印该垃圾。
你该怎么办?
首先丢弃 fscanf 中的奇怪格式:第一个与 fgets
没有太大区别,第二个期望行尾后跟 s
字符。
因此,如果您想逐行阅读,只需使用 fgets
计算实际阅读的行数:
for(i=0; i<100; i++)
{
int l;
if (NULL == fgets(line[i], sizeof(line[i]), stdin)) break;
l = strlen(line[i]) - 1;
while ((l>0) && (strchr(" \t\r\n", line[i][l]) != NULL) {
line[i][l--] = '[=10=]'; //Remove any trailing 'white space' characters
}
nblines = i - 1; // number or lines actually read
但是因为你知道行的格式而且很简单你可以直接扫描:
char name[100][41], firstname[100][41];
int age(100);
int i, numlig;
for(numlig=0; numlig<100; numlig++) {
if (3 != scanf("%[^,],%s%d", name[i], lastname[i], age + i)) {
break;
}
}
或者如果你想严格控制每一行发生的事情:
char name[100][41], firstname[100][41], line[41];
int age(100);
int i, numlig;
for(numlig=0; numlig<100; numlig++) {
if (NULL == fgets(line, sizeof(line), stdin)) { break; }
if (3 != sscanf(line, "%[^,],%s%d", name[i], lastname[i], age + i)) {
break;
}
}
有多种方法可以完成读取数据并将数据分成 first
、last
和 age
。最有意义的是使用包含每个姓名和年龄的简单 struct
,然后创建一个结构数组来保存您的数据。
很少有地方需要使用 fscanf
。 scanf
系列函数在处理除每行 完全相同格式 之外的任何内容时非常不灵活。通常你会想要使用 line-oriented 输入(fgets
然后用 strtok
或 sscanf
解析你的数据)。但是,这种情况符合条件。
这是一个使用结构保存数据和 fscanf
输入的简短示例:
#include <stdio.h>
#define MAXP 20
typedef struct {
char first[20];
char last[20];
int age;
} person;
int main (int argc, char **argv) {
size_t i, idx = 0; /* initialize all variables */
person p[MAXP] = {{"", "", 0}};
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (idx < MAXP && /* read each line, separate first, last, age */
fscanf (fp, "%[^,],%s%d%*c", p[idx].last, p[idx].first, &p[idx].age) == 3)
idx++;
if (fp != stdin) fclose (fp); /* close file */
for (i = 0; i < idx; i++) /* output data */
printf (" p[%2zu] '%s %s' is %d years old.\n",
i, p[i].first, p[i].last, p[i].age);
return 0;
}
输入文件
$ cat dat/names.txt
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
例子Use/Output
$ ./bin/person <dat/names.txt
p[ 0] 'Elizabeth Ryan' is 62 years old.
p[ 1] 'Osborne McIntyre' is 84 years old.
p[ 2] 'Kristin DuMond' is 18 years old.
p[ 3] 'Lois Larson' is 42 years old.
p[ 4] 'Trinity Thorpe' is 15 years old.
p[ 5] 'Pedro Ruiz' is 35 years old.
p[ 6] 'Mohammed Ali' is 60 years old.
p[ 7] 'Indura Vashti' is 20 years old.
示例使用 fgets/sscanf
您基本上可以用 fgets
和 sscanf
做同样的事情。这是一个使用该组合的简短示例:
#include <stdio.h>
enum { MAXP = 20, MAXC = 128 };
typedef struct {
char first[20];
char last[20];
int age;
} person;
int main (int argc, char **argv) {
size_t i, idx = 0; /* initialize all variables */
char buf[MAXC] = "";
person p[MAXP] = {{"", "", 0}};
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (idx < MAXP && fgets (buf, MAXC, fp) &&
sscanf (buf, "%[^,],%s%d",
p[idx].last, p[idx].first, &p[idx].age) == 3)
idx++;
if (fp != stdin) fclose (fp); /* close file */
for (i = 0; i < idx; i++) /* output data */
printf (" p[%2zu] '%s %s' is %d years old.\n",
i, p[i].first, p[i].last, p[i].age);
return 0;
}
仔细阅读,如果您有任何问题,请告诉我。
不管这个文件有多少人,都要打印30个人。在您的情况下,该文件仅包含 8 个人,其余 22 行(从 line[8]
到 line[29]
)持有的值是垃圾值,因为它们从未被初始化。结果打印出奇怪的字符。
精炼代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char first[100][40], last[100][40];
int age[100];
size_t i = 0;
FILE *file = fopen(argv[1], "r");
if(!file) {
printf("Could not open file. Exiting application.");
return 1;
}
while(fscanf(file, " %[^,],%s%d", first[i], last[i], &age[i]) == 3)
{
i++;
}
size_t num = i;
fclose(file);
for (i = 0; i < num; i++)
printf("%s, %s\t%d\n", first[i], last[i], age[i]);
return 0;
}
事实上,你不需要先读一整行。相反,直接从文件中扫描预期数据。
我正在尝试读取包含字符串和数字的文本文件并保存到它们各自的数组中。这是我正在尝试读取的内容文本文件
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
我需要在并行数组中保存 repescitve 人的姓氏、名字和年龄。 (所以我需要在阅读时丢弃逗号)。 这是我目前所拥有的。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char line[100][41];
char junk[100];
int i;
FILE *file = fopen(argv[1], "r");
if(!file) {
printf("Could not open file. Exiting application.");
return 1;
}
for(i=0; i<100; i++)
{
fscanf(file, "%[^\n]", line[i]); //Get text
fscanf(file,"%[ \n\t\r]s",junk); //Remove any 'white space' characters
}
fclose(file);
for (i=0; i<30; i++)
printf("%s\n",line[i]);
return 0;
}
我已经在 IDE 中传递了文件参数。我在输出末尾得到了很多特殊字符。
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
┌
t╠╠
$
M
v
9 Rì
xá
╚
±
t/╗₧8
¿≡`
Tq töq t4≤`
ÿv
h(((( Hääääääääääüüüüüüéééééé
为什么我要读那些特殊字符?以及如何丢弃逗号并保存到三个不同的数组中?
你不看那些特殊字符。它们恰好存在于你的数组中,因为它是一个非静态持续时间的未初始化数组。因此,当您到达文件末尾时,因为您没有测试输入函数的结果,所以您将垃圾留在缓冲区中,稍后打印该垃圾。
你该怎么办?
首先丢弃 fscanf 中的奇怪格式:第一个与 fgets
没有太大区别,第二个期望行尾后跟 s
字符。
因此,如果您想逐行阅读,只需使用 fgets
计算实际阅读的行数:
for(i=0; i<100; i++)
{
int l;
if (NULL == fgets(line[i], sizeof(line[i]), stdin)) break;
l = strlen(line[i]) - 1;
while ((l>0) && (strchr(" \t\r\n", line[i][l]) != NULL) {
line[i][l--] = '[=10=]'; //Remove any trailing 'white space' characters
}
nblines = i - 1; // number or lines actually read
但是因为你知道行的格式而且很简单你可以直接扫描:
char name[100][41], firstname[100][41];
int age(100);
int i, numlig;
for(numlig=0; numlig<100; numlig++) {
if (3 != scanf("%[^,],%s%d", name[i], lastname[i], age + i)) {
break;
}
}
或者如果你想严格控制每一行发生的事情:
char name[100][41], firstname[100][41], line[41];
int age(100);
int i, numlig;
for(numlig=0; numlig<100; numlig++) {
if (NULL == fgets(line, sizeof(line), stdin)) { break; }
if (3 != sscanf(line, "%[^,],%s%d", name[i], lastname[i], age + i)) {
break;
}
}
有多种方法可以完成读取数据并将数据分成 first
、last
和 age
。最有意义的是使用包含每个姓名和年龄的简单 struct
,然后创建一个结构数组来保存您的数据。
很少有地方需要使用 fscanf
。 scanf
系列函数在处理除每行 完全相同格式 之外的任何内容时非常不灵活。通常你会想要使用 line-oriented 输入(fgets
然后用 strtok
或 sscanf
解析你的数据)。但是,这种情况符合条件。
这是一个使用结构保存数据和 fscanf
输入的简短示例:
#include <stdio.h>
#define MAXP 20
typedef struct {
char first[20];
char last[20];
int age;
} person;
int main (int argc, char **argv) {
size_t i, idx = 0; /* initialize all variables */
person p[MAXP] = {{"", "", 0}};
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (idx < MAXP && /* read each line, separate first, last, age */
fscanf (fp, "%[^,],%s%d%*c", p[idx].last, p[idx].first, &p[idx].age) == 3)
idx++;
if (fp != stdin) fclose (fp); /* close file */
for (i = 0; i < idx; i++) /* output data */
printf (" p[%2zu] '%s %s' is %d years old.\n",
i, p[i].first, p[i].last, p[i].age);
return 0;
}
输入文件
$ cat dat/names.txt
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
例子Use/Output
$ ./bin/person <dat/names.txt
p[ 0] 'Elizabeth Ryan' is 62 years old.
p[ 1] 'Osborne McIntyre' is 84 years old.
p[ 2] 'Kristin DuMond' is 18 years old.
p[ 3] 'Lois Larson' is 42 years old.
p[ 4] 'Trinity Thorpe' is 15 years old.
p[ 5] 'Pedro Ruiz' is 35 years old.
p[ 6] 'Mohammed Ali' is 60 years old.
p[ 7] 'Indura Vashti' is 20 years old.
示例使用 fgets/sscanf
您基本上可以用 fgets
和 sscanf
做同样的事情。这是一个使用该组合的简短示例:
#include <stdio.h>
enum { MAXP = 20, MAXC = 128 };
typedef struct {
char first[20];
char last[20];
int age;
} person;
int main (int argc, char **argv) {
size_t i, idx = 0; /* initialize all variables */
char buf[MAXC] = "";
person p[MAXP] = {{"", "", 0}};
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (idx < MAXP && fgets (buf, MAXC, fp) &&
sscanf (buf, "%[^,],%s%d",
p[idx].last, p[idx].first, &p[idx].age) == 3)
idx++;
if (fp != stdin) fclose (fp); /* close file */
for (i = 0; i < idx; i++) /* output data */
printf (" p[%2zu] '%s %s' is %d years old.\n",
i, p[i].first, p[i].last, p[i].age);
return 0;
}
仔细阅读,如果您有任何问题,请告诉我。
不管这个文件有多少人,都要打印30个人。在您的情况下,该文件仅包含 8 个人,其余 22 行(从 line[8]
到 line[29]
)持有的值是垃圾值,因为它们从未被初始化。结果打印出奇怪的字符。
精炼代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char first[100][40], last[100][40];
int age[100];
size_t i = 0;
FILE *file = fopen(argv[1], "r");
if(!file) {
printf("Could not open file. Exiting application.");
return 1;
}
while(fscanf(file, " %[^,],%s%d", first[i], last[i], &age[i]) == 3)
{
i++;
}
size_t num = i;
fclose(file);
for (i = 0; i < num; i++)
printf("%s, %s\t%d\n", first[i], last[i], age[i]);
return 0;
}
事实上,你不需要先读一整行。相反,直接从文件中扫描预期数据。