简体   繁体   English

如何从文件中读取一行?

[英]How to read a line from file?

I have to read a txt file with lines formated like this: 我必须读取一个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)

Each line will feed a struct with its data (the 5 numbers or letters in it). 每一行都将为结构提供数据(其中包含5个数字或字母)。
What's the best way to read the line and get the strings I want? 阅读该行并获得我想要的字符串的最佳方法是什么?
I'm currently using a long sequence of conditions using fgetc but that seems ugly and not very smart. 我目前正在使用fgetc使用一系列条件,但这看起来很难看而且不是很聪明。
I can't use arrays because the lines may vary in size if the numbers have two digits. 我不能使用数组,因为如果数字有两位数,行的大小可能会有所不同。

我想你可以解析它:

fscanf(file,"%c: (%c, %c), (%c, %c)", &first,&second,&third,&fourth,&fifth);

Use fgets() : 使用fgets()

#include <stdio.h>

int main(void)
{
  char line[256];
  while(fgets(line, sizeof(line), stdin) != NULL)  // fgets returns NULL on EOF
  {
    // process line; line is guaranteed to be null-terminated, but it might not end in a
    // newline character '\n' if the line was longer than the buffer size (in this case,
    // 256 characters)
  }

  return 0;
}
#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;
}

Sample run: 样品运行:

$ ./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

If the last value in the input is more than 10 characters it will be truncated with no indication of error, if this is not acceptable you can use the %c conversion specifier as a sixth argument to capture the next character after the last value and make sure it is a closing parenthesis. 如果输入中的最后一个值超过10个字符,它将被截断而没有错误指示,如果这是不可接受的,您可以使用%c转换说明符作为第六个参数来捕获最后一个值之后的下一个字符并使确定它是一个右括号。

我记得fgets()和sscanf()

fscanf works pretty nice, but you'll have to use string conversions, because chars wouldn't work for numbers with more than one digit. fscanf工作得很好,但你必须使用字符串转换,因为字符不适用于多个数字的数字。

Isn't this some kind of homework? 这不是一种功课吗?

#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);
}
#include
void
f()
{
    FILE* fp;

    if ( (fp = fopen("foo.txt", "r")) == NULL)
    {
        perror("fopen");
        return;
    }

    char ch[5];
    while (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。

Assuming you have the correct variables, this should work: 假设你有正确的变量,这应该工作:

 fscanf(fp, "%[^:]: (%[^,], %[^)]), (%[^,], %[^)])", a, b, c, d, e);

fp is a file pointer and "a" to "e" are char pointers fp是文件指针,“a”到“e”是char指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM