gpt4 book ai didi

c - C中具有可变数量的字符串和整数标记的多行输入

转载 作者:太空宇宙 更新时间:2023-11-04 06:54:02 24 4
gpt4 key购买 nike

我的输入文件看起来像这样-

# 4
INS 0 3
DEC 0 0
DEL
INS 1 2
DEC 1 0
DEL
INS 2 1
DEC 2 0
INS 3 3

整个模块在输入中多次出现。我想逐行读取输入,然后根据第一个单词(以空格分隔),使用附加值执行必要的功能(如果存在,如 #INSDEC操作)。

我如何允许读取相同的可能的额外值?

到目前为止,我使用 fread 逐行读取它然后拆分它,但 IMO 的工作量太大了。我尝试使用 scanf("%[^\n]\n", variable) 但我又需要对其进行标记化。

此外,当尝试使用 scanf("%[^\n] %[0-9] %[0-9]\n", var1, var2, var3) 指定需要使用 var2 和 var3 作为字符数组。这减少了标记化的需要,但提供了垃圾输入。

有没有更简单的方法来做同样的事情?

Ps- 我在 Ubuntu 17.10 上使用 C。

提前致谢

最佳答案

继续评论,使用 scanf 为新的(和不太新的)C 程序员输入是一个雷区。 scanf 不会读取并包含结尾的 '\n',除非您在您的格式字符串 中明确说明它。 转换说明符 根据您读取的是数字、字符还是字符串值,以不同方式处理前导空格。

这是在获取用户输入时推荐面向行的输入函数(例如 fgets(或 POSIX getline))的主要原因之一 - - 它们提供了一种简单的方法来验证是否读取了完整的行(例如获取长度并检查最后一个字符是否为 '\n')并始终如一地处理输入缓冲区中等待的字符。

此外,使用 fgets 然后解析缓冲区允许分别验证 (1) 读取和 (2) 信息解析。您可以使用 string.h 中符合要求的任何函数解析输入,使用 sscanf 或者简单地通过一个指针(或一对指针)沿着缓冲区向下移动检查每个字符并采取任何必要的行动来利用生产线的每一部分。

一个使用sscanf 进行解析的简单示例可能类似于以下内容。代码期望文件名作为第一个参数读取,如果没有给出参数,它将默认从 stdin 读取:

#include <stdio.h>
#include <string.h>

#define DEL "DEL" /* if you need constants, define them */
enum { MAXARG = 3, MAXC = 512 };

int main (int argc, char **argv) {

int n1, n2; /* integer values from line */
size_t ndx = 0; /* line index */
char buf[MAXC] = "", /* buffer for line */
cmd[MAXARG+1] = ""; /* buffer for 3-char command */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}

while (fgets (buf, MAXC, fp)) { /* read each line in file */
size_t len = 0; /* buf length */

if (*buf == '#') { /* check if first char in line is '#', discard */
fprintf (stderr, "line[%2zu] - discarding comment line.\n", ndx);
ndx++;
continue;
}

len = strlen (buf); /* get length */
if (len && buf[len - 1] != '\n') { /* validate last char '\n' */
fprintf (stderr, "error: line too long, chars remain unread.\n");
break;
}

/* check for 3 values, then 1 value == "DEL", otherwise throw error */
if (sscanf (buf, "%3s %d %d", cmd, &n1, &n2) == MAXARG)
printf ("line[%2zu] (3 vals) : %s %d %d\n", ndx, cmd, n1, n2);
else if (strncmp (DEL, buf, MAXARG) == 0)
printf ("line[%2zu] (1 val) : %s\n", ndx, cmd);
else
fprintf (stderr, "error: invalid line: %zu\n", ndx);

ndx++;
}

if (fp != stdin) fclose (fp); /* close file if not stdin */

return 0;
}

示例使用/输出

使用您的数据文件,将按如下方式读取和解析数据。请注意,初始标签表明是否从该行(零索引)中解析了 1 个值或 3 个值:

$ ./bin/misclines <dat/misclines.txt
line[ 0] - discarding comment line.
line[ 1] (3 vals) : INS 0 3
line[ 2] (3 vals) : DEC 0 0
line[ 3] (1 val) : DEL
line[ 4] (3 vals) : INS 1 2
line[ 5] (3 vals) : DEC 1 0
line[ 6] (1 val) : DEL
line[ 7] (3 vals) : INS 2 1
line[ 8] (3 vals) : DEC 2 0
line[ 9] (3 vals) : INS 3 3

检查一下,如果您还有其他问题,请告诉我。

关于c - C中具有可变数量的字符串和整数标记的多行输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47277307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com