提问人:al366io 提问时间:4/22/2022 最后编辑:anastaciual366io 更新时间:4/24/2022 访问量:218
如何读取文件并解析它
How to read from a file and parse it
问:
我有一个文件.txt包含一些格式如下的值:
0,30,25,10
现在,我打开文件并将其存储到一个数组中
char imposta_tratt[300];
FILE *fp;
fp = fopen("/home/pi/Documents/imposta_trattamento.txt", "r");
if (fp == 0) return;
fread(imposta_tratt, sizeof(imposta_tratt), 1, fp);
fclose(fp);
现在我希望数组中填满我的数据。我有用 a 分隔的值,所以我继续解析它:,
const char delim[2] = ",";
int t=0;
char *token = strtok(imposta_tratt, delim);
while (token!=NULL){
strcpy(tratt[t],token);
token = strtok(NULL, delim);
tratt[t]=token;
t++;
}
在这里,参考文件.txt中的内容,我希望有等等,但似乎我遗漏了一些东西,因为它不是这样的。tratt[0]=0; tratt[1]=30; tratt[2]=25;
我想要的只是将 txt 文件的值存储在单个变量中。有人可以帮忙吗?
答:
0赞
OTheDev
4/22/2022
#1
假设有内容"in.txt"
0,30,25,10
下面的程序用于将整数逐个读入数组。当我们使用 读取整数时,我们确保它的返回值符合预期。如果没有,我们将关闭文件并退出。如果返回值与预期不符,程序还会打印发生的错误类型。目前,如果发生任何错误,程序将停止。但是,如果您愿意,您可以根据发生的错误使程序的行为有所不同。fscanf
tratt
fscanf
fscanf
作为输出,程序将读取到数组中的所有整数打印出来。输出为tratt
0
30
25
10
现在这个程序假设我们知道要读入的元素的数量。如果我们不这样做,我们可以允许在数组需要更多元素时动态分配更多内存,或者可能包含一个数据结构,例如,在文件的开头/结尾记录有关文件的信息,例如文件中的数字数和数据类型(二进制文件最适合此)。这些只是其中的几种可能性。tratt
"in.txt"
更好的方法可能是逐个读取字符(例如,使用 )并使用将字符数字序列转换为字符数字(我会采用类似的方法)。getc
strtol
long int
然而,这种方法更简洁,应该就足够了。
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "in.txt"
#define MAX_LEN 4
int main(void) {
int i, tratt[MAX_LEN];
FILE *fp = fopen(FILE_NAME, "r"); /* open file for reading */
/* if cannot open file */
if (fp == NULL) {
printf("Cannot open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
/* read integer, checking return value of scanf as expected */
if (fscanf(fp, "%d", &tratt[0]) != 1) {
if (ferror(fp))
printf("fscanf: read error\n");
else if (feof(fp))
printf("fscanf: end of file\n");
else
printf("fscanf: matching failure\n");
fclose(fp);
exit(EXIT_FAILURE);
}
for (i = 1; i < MAX_LEN; i++)
/* read comma plus integer, checking return value of scanf */
if (fscanf(fp, ",%d", &tratt[i]) != 1) {
if (ferror(fp))
printf("fscanf: read error\n");
else if (feof(fp))
printf("fscanf: end of file\n");
else
printf("fscanf: matching failure\n");
fclose(fp);
exit(EXIT_FAILURE);
}
fclose(fp); /* close file */
/* print integers stored in tratt */
for (i = 0; i < MAX_LEN; i++)
printf("%d\n", tratt[i]);
return 0;
}
1赞
Zakk
4/22/2022
#2
您要实现的目标可以简单地使用以下方法完成:fgets()
bool read_file_content(const char *filename, const size_t tsizemax, int tratt[tsizemax], size_t *tsize, const char *delim)
{
// Attempt to open filename.
FILE *fp = fopen(filename, "r");
if (!fp) return false; // Return false upon failure.
// Try to read one line. If you have more, you need a while loop.
char imposta_tratt[300];
if (!fgets(imposta_tratt, sizeof imposta_tratt, fp)) {
fclose(fp);
return false;
}
*tsize = 0;
char tmp[300]; // Temporary buffer. Used for conversion into int.
char *token = strtok(imposta_tratt, delim);
while (token && *tsize < tsizemax) {
strncpy(tmp, token, sizeof tmp);
tratt[(*tsize)++] = atoi(tmp);
token = strtok(NULL, delim);
}
fclose(fp);
return true;
}
const char *filename
:要解析的文件。const size_t tsizemax
:阵列的最大大小。控制大小很重要,否则代码将出现缓冲区溢出(例如,当文件包含超过 100 个标记时)。tratt
int tratt[tsizemax]
:将保存值的数组。size_t *tsize
:读取的令牌数(与 )。tsizemax
const char *delim
:分隔符,在您的例子中为 a .,
这是你的:main()
int main(void)
{
int tratt[100];
size_t size = 0;
if (!read_file_content("in.txt", 100, tratt, &size, ",")) {
puts("Failed");
return 1;
}
for (size_t i = 0; i < size; ++i)
printf("%d\n", tratt[i]);
}
输出:
0
30
25
10
评论
size_t len = fread(imposta_tratt, 1, sizeof(imposta_tratt) - 1, fp); imposta_tratt[len] = 0;
fread
fgets()
fread()
fgets
strtok
const char delim[] = ",\n";
delim[2]
delim[3]
0
"0"