C 如何从文件中读取一行?
我必须读取一个txt文件,其中的行格式如下: 1: (G, 2), (F, 3) 2: (G, 2), (F, 3) 3: (F, 4), (G, 5) 4: (F, 4), (G, 5) 5: (F, 6), (c, w) 6: (p, f), (G, 7) 7: (G, 7), (G, 7) w: (c, w), (c, w) 1:(G,2),(F,3) 2:(G,2),(F,3) 3:(F,4),(G,5) 4:(F,4),(G,5) 5:(F,6),(c,w) 6:(p,f),(G,7) 7:(G,7),(G,7) w:(c,w),(c,w) 每行将向结构提供数据(其中的5个数字或字母)。C 如何从文件中读取一行?,c,file-io,C,File Io,我必须读取一个txt文件,其中的行格式如下: 1: (G, 2), (F, 3) 2: (G, 2), (F, 3) 3: (F, 4), (G, 5) 4: (F, 4), (G, 5) 5: (F, 6), (c, w) 6: (p, f), (G, 7) 7: (G, 7), (G, 7) w: (c, w), (c, w) 1:(G,2),(F,3) 2:(G,2),(F,3) 3:(F,4),(G,5) 4:(F,4),(G,5) 5:(F,6),(c,w) 6:(p,f),(G,7)
读这行并得到我想要的字符串的最佳方式是什么?
我目前正在使用
fgetc
使用一长串条件,但这看起来很难看,也不是很聪明。我不能使用数组,因为如果数字有两个数字,行的大小可能会不同。fgets()和sscanf(),我记得使用
fgets()
:
#包括
内部主(空)
{
字符行[256];
while(fgets(line,sizeof(line),stdin)!=NULL)//fgets在EOF上返回NULL
{
//进程行;行保证以null结尾,但它可能不会以
//换行符'\n',如果行长于缓冲区大小(在本例中,
//(256个字符)
}
返回0;
}
我认为您可以按照以下方式对其进行分析:
fscanf(file,"%c: (%c, %c), (%c, %c)", &first,&second,&third,&fourth,&fifth);
fscanf的工作原理相当不错,但您必须使用字符串转换,因为字符不能用于具有多个数字的数字 这不是什么家庭作业吗
#include <stdio.h>
void main(int argc, char **argv) {
FILE * f;
f = fopen(argv[1], "r");
while (1) {
char char_or_num[32][5]; // five string arrays, up to 32 chars
int i;
int did_read;
did_read = fscanf(f, "%32[0-9a-zA-Z]: (%32[0-9a-zA-Z], %32[0-9a-zA-Z]), (%32[0-9a-zA-Z], %32[0-9a-zA-Z])\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
if (did_read != 5) {
break;
}
printf("%s, %s, %s, %s, %s\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
}
fclose(f);
}
#包括
void main(整型argc,字符**argv){
文件*f;
f=fopen(argv[1],“r”);
而(1){
char char_或_num[32][5];//五个字符串数组,最多32个字符
int i;
你读了什么;
你读过吗?=fscanf(f,“%32[0-9a-zA-Z]:(%32[0-9a-zA-Z],%32[0-9a-zA-Z]),(%32[0-9a-zA-Z],%32[0-9a-zA-Z])\n”,char或_num[0],char或_num[1],char或_num[2],char或_num[3],char或_num[4]);
如果(读过!=5){
打破
}
printf(“%s、%s、%s、%s\n”、char_或_num[0]、char_或_num[1]、char_或_num[2]、char_或_num[3]、char_或_num[4]);
}
fclose(f);
}
#包括
无效的
f()
{
文件*fp;
if((fp=fopen(“foo.txt”,“r”))==NULL)
{
佩罗尔(“福彭”);
返回;
}
char-ch[5];
而(fscanf(fp,“%c:(%c,%c),(%c,%c)\n“,&ch[0],&ch[1],&ch[2],&ch[3],&ch[4])==5)
{
printf(“-->%c%c%c%c%c\n”,ch[0],ch[1],ch[2],ch[3],ch[4]);
}
fclose(fp);
}
基本上,您必须通过fgetpos保存文件ptr的位置,走到行的末尾(不管您如何定义),保存该大小,将fsetpos保存到上一个位置,分配足够大的缓冲区来容纳行,然后使用新的缓冲区调用fread。假设您有正确的变量,这应该可以:
fscanf(fp, "%[^:]: (%[^,], %[^)]), (%[^,], %[^)])", a, b, c, d, e);
fp是一个文件指针
和“a”到“e”是字符指针
#include <stdio.h>
int main (void)
{
char buf[81]; /* Support lines up to 80 characters */
char parts[5][11]; /* Support up to 10 characters in each part */
while (fgets(buf, sizeof(buf), stdin) != NULL)
{
if (sscanf(buf, "%10[^:]: (%10[^,], %10[^)]), (%10[^,], %10[^)])",
parts[0], parts[1], parts[2], parts[3], parts[4]) == 5)
{
printf("parts: %s, %s, %s, %s, %s\n",
parts[0], parts[1], parts[2], parts[3], parts[4]);
}
else
{
printf("Invalid input: %s", buf);
}
}
return 0;
}
如果输入中的最后一个值超过10个字符,它将被截断而不显示错误,如果这是不可接受的,您可以使用
%c
转换说明符作为第六个参数来捕获最后一个值后的下一个字符,并确保它是右括号。我尝试过这样做,但只有分段错误,我会再试一次,以防万一我忽略了一些实际操作,如果第一、第二、第三个指针没有分配给您需要执行的操作:fscanf(文件,“%c:(%c,%c)”,&first,&second,&third);或者你会出现seg错误,因为你将取消引用无效的地址…很好的呼叫,已修复…我无论如何都不是C开发人员。这不会处理超过一个字符长的值,@Gabe表示数字可能至少有2位。它在第一行换行时也会遇到麻烦!你根本不必这么做。fgets()工作得非常好。如果您不介意fscanf()的所有警告,那么它也会起作用。这两个都在这里演示。哇-那将是一项艰苦的工作;对了,不必要的辛苦工作。使用fgets()作为第一选择;fscanf()如果你觉得自己很勇敢,可以处理换行符。使用fgets()的问题是,它会让你猜测行的大小,如果你不仔细、尽职尽责地检查返回值以确保得到整行,你的单个函数调用可能会变成大量调用,直到你得到正确的大小。看起来像是家庭作业,如果您没有使用“void main(…)”,请添加家庭作业标签;这是不标准的。
fscanf(fp, "%[^:]: (%[^,], %[^)]), (%[^,], %[^)])", a, b, c, d, e);
#include <stdio.h>
int main (void)
{
char buf[81]; /* Support lines up to 80 characters */
char parts[5][11]; /* Support up to 10 characters in each part */
while (fgets(buf, sizeof(buf), stdin) != NULL)
{
if (sscanf(buf, "%10[^:]: (%10[^,], %10[^)]), (%10[^,], %10[^)])",
parts[0], parts[1], parts[2], parts[3], parts[4]) == 5)
{
printf("parts: %s, %s, %s, %s, %s\n",
parts[0], parts[1], parts[2], parts[3], parts[4]);
}
else
{
printf("Invalid input: %s", buf);
}
}
return 0;
}
$ ./test
1: (G, 2), (F, 3)
2: (G, 2), (F, 3)
3: (F, 4), (G, 5)
4: (F, 4), (G, 5)
5: (F, 6), (c, w)
6: (p, f), (G, 7)
7: (G, 7), (G, 7)
w: (c, w), (c, w)
parts: 1, G, 2, F, 3
parts: 2, G, 2, F, 3
parts: 3, F, 4, G, 5
parts: 4, F, 4, G, 5
parts: 5, F, 6, c, w
parts: 6, p, f, G, 7
parts: 7, G, 7, G, 7
parts: w, c, w, c, w