我需要从使用C的文件中读取。
#include <stdio.h>
struct record{
char name[2];
int arrival_time;
int job_length;
int job_priority;
};
const int MAX = 40;
main(){
struct record jobs[MAX];
FILE *f;
fopen("data.dat","rb");
int count =0;
while(fscanf(f, "%c%c %d %d %d", &jobs[count].name, &jobs[count].arrival_time, &jobs[count].job_length, &jobs[count].job_priority) != EOF){
count++;
}
int i;
for(i =0;i<count;i++){
printf("%c%c %d %d %d", &jobs[count].name, &jobs[count].arrival_time, &jobs[count].job_length, &jobs[count].job_priority);
}
}
数据文件的格式如下:
A1 3 3 3
B1 4 4 4
C1 5 5 5
...
第一个是char [2],另外三个是int。在文件结束之前,我无法正确读取代码。
之前有人遇到过这个问题吗?
更新了代码。
答案 0 :(得分:1)
您需要获取该行并根据您要阅读的类型对其进行解析。
while(fgets(line, 80, fr) != NULL)
{
/* get a line, up to 80 chars from fr. done if NULL */
sscanf (line, "%s %d %d %d", &myText, &int1, &int2, &int3);
}
答案 1 :(得分:1)
需要进行一些修改 - 最值得注意的是,您需要引用jobs
结构数组:
#include <stdio.h>
struct record{
char name[2];
int arrival_time;
int job_length;
int job_priority;
};
const int MAX = 40;
int main(void)
{
struct record jobs[MAX];
int i = 0;
int j;
FILE *f = fopen("data.dat","rb");
while (fscanf(f, "%c %d %d %d", &jobs[i].name[0], &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4 && i < MAX)
i++:
for (j = 0; j < i; j++)
printf("%c %d %d %d\n", jobs[j].name[0], jobs[j].arrival_time,
jobs[j].job_length, jobs[j].job_priority);
return(0);
}
我确保循环不会溢出数组。我打印出数据(这是检查你已经阅读过你预期的最基本的形式)。最微妙的问题是使用jobs[i].name[0]
;这是阅读和打印单个字符所必需的。无法保证jobs[i].name[1]
中有任何特定价值;特别是,它很可能不是NUL '\0'
,因此名称不会终止。使用单个字符名称似乎有点奇怪;你可能希望在结构中有一个更长的字符串:
char name[MAX]; // Lazy reuse of MAX for two different purposes!
fscanf(f, "%.39s ...", jobs[i].name, ...
printf("%s ...", jobs[i].name, ...
现在不需要&
。 %.39s
表示法用于读取长度受限的字符串,直到第一个空格。请注意,字符串中的大小比数组的大小小1。通过sprintf()
创建格式字符串以获得正确的大小通常是最简单的。
代码没有错误检查fopen()
语句。
你的代码打印出A 1 3 3而不是A1 3 3 3.我试图向它添加第二个%c而它没有解决它。
我讨论了比一个角色更长的名字......
如果您需要阅读“A1”,则需要name
成员更大,以便您可以空终止字符串,并且需要使用%s
而不是%c
读取值,你需要丢失&
和下标,你需要保护你的代码免受缓冲区溢出(因为你期望'A1',有人将不可避免地输入'A1B2C3D4D5F6G7H8I9J10K11L12M13'并对你造成严重破坏代码,如果你不防止缓冲区溢出。顺便说一句,fscanf()
(从== EOF
到!= 4
的结果测试的变化也是对输入格式错误的保护;你可以一般情况下,无需读取任何字符即可获得零成功转换 - 尽管您的%c
每次迭代会吃一个字符。)
#include <stdio.h>
struct record{
char name[4];
int arrival_time;
int job_length;
int job_priority;
};
const int MAX = 40;
int main(void)
{
struct record jobs[MAX];
int i = 0;
int j;
FILE *f = fopen("data.dat","rb");
while (fscanf(f, "%.3s %d %d %d", jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4 && i < MAX)
i++:
for (j = 0; j < i; j++)
printf("%s %d %d %d\n", jobs[j].name, jobs[j].arrival_time,
jobs[j].job_length, jobs[j].job_priority);
return(0);
}
答案 2 :(得分:0)
注意:这不是最好的方法,其他人使用格式字符串和fgets来解决更简单的解决方案,这基本上可以在一个简单的行中完成我想做的事情。
我假设你想要这样的东西。请注意,我没有对此进行过测试,因为我很快就写完了。
#include <stdio.h>
FILE *fileInput;
main()
{
char* path="whatever.txt";
fileInput = fopen(path, "r");
int i=0;
while (fgets(line,100,fi)!=NULL)
{
token[0] = strtok(line, " ");
//now you can do whatever you wanna do with token[0]
//in your example, token[0] is A1 on the first iteration, then B1, then C1
while(token[i]!= NULL)
{
//now token[i] can be converted into an int, probably using atoi
//in your example, token[i] will reference 3 (3 times) then 4, etc
}
}
}
希望它有所帮助!
答案 3 :(得分:0)
不,这些行不包含整数。每一行都是一个字符串,可以很容易地解析成四个较短的字符串。然后,每个字符串都可以被提取并存储在结构中,或者转换为可以存储在结构中的整数。
scanf
函数是人们在数据格式简单直接时进行此类输入字符串解析的常用方法。