Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何从文件中读取一行?_C_File Io - Fatal编程技术网

C 如何从文件中读取一行?

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)

我必须读取一个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个数字或字母)。
读这行并得到我想要的字符串的最佳方式是什么?
我目前正在使用
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