我正在尝试读取包含字符串和数字的文本文件并保存到各自的数组中。这是我正在尝试阅读的内容文本文件
Ryan, Elizabeth 62
McIntyre, Osborne 84
DuMond, Kristin 18
Larson, Lois 42
Thorpe, Trinity 15
Ruiz, Pedro 35
Ali, Mohammed 60
Vashti, Indura 20
我需要在并行数组中保存重复名字的姓氏,名字和年龄。 (所以我在阅读时需要丢弃逗号)。 这是我到目前为止所做的。
#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ääääääääääüüüüüüéééééé
为什么我要阅读所有这些特殊字符?我怎样才能丢弃逗号并保存到三个不同的数组中?
答案 0 :(得分:0)
您没有阅读这些特殊字符。它们碰巧存在于您的数组中,因为它是一个未初始化的非静态持续时间数组。因此,当您到达文件末尾时,因为您没有测试输入函数的结果,所以将垃圾留在缓冲区中,然后打印出垃圾。
你应该怎么做?
首先抛弃你在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--] = '\0'; //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;
}
}
答案 1 :(得分:0)
您可以通过多种方式完成阅读并将数据分为first
,last
和age
。最有意义的是使用包含每个名称和年龄的简单struct
,然后创建一个struct数组来保存数据。
您可能希望使用fscanf
的地方很少。除了每行的完全相同的格式之外,scanf
系列函数都非常不灵活。通常,您需要使用面向行的输入(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
示例使用/输出
$ ./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;
}
仔细看看,如果您有任何问题,请告诉我。
答案 2 :(得分: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;
}
事实上,您不需要先阅读整行。而是直接扫描文件中的预期数据。