【问题标题】:How to read numbers from a text file properly?如何正确读取文本文件中的数字?
【发布时间】:2016-05-15 17:22:31
【问题描述】:

我想用 C 编写一个彩票程序,它将前几周的选定数字读入一个数组。我有一个文本文件,其中有 5 列用制表符分隔。我的问题如下:

  • 我应该用什么分隔列? (例如逗号、分号、制表符或其他)
  • 我应该在最后一行包含一种 EOF 吗? (例如 -1,“EOF”)是否有任何公认的或“官方”的约定可以做到这一点?
  • 我应该使用哪个函数来读取数字?是否有任何正确或“可接受”的方式从文本文件中读取数据?

我曾经为“谁想成为亿万富翁”游戏编写了一个 C 程序。在那篇文章中,我使用了一种函数,将每一行读入一个数组,该数组大到可以容纳一整行。之后,我将其数据分成如下变量:

line: "text1";"text2";"text3";"text4"endline (-> line loaded into a buffer array)
text1 -> answer1 (until reaching the semicolon)
text2 -> answer2 (until reaching the semicolon)
text3 -> answer3 (until reaching the semicolon)
text4 -> answer4 (until reaching the end of the line)
endline -> start over, that is read a new line and separate its contents into variables.

它工作正常,但我不知道它对程序员来说是否足够好。 (顺便说一句,我还不是程序员,我在大学学习计算机科学)

欢迎任何答案和建议。提前感谢您的帮助!

【问题讨论】:

  • 虽然“制表符”是“制表符”的基础,而 Unicode 定义了 U+0009 水平制表符和 U+000B 垂直制表符,但大多数人会写“制表符”或“制表位”而不是“制表符” ' 或 'tabulation'(对 U+000B 使用 'vertical tab')。
  • 冒号 : 或分号 ; 是数字数据的绝佳分隔符。建议不要使用tabs,因为它们往往会使数据更难于人类阅读,因为它们在查看文本文件时不一定很容易看到。强烈建议通过换行符\n' 分隔每组数字,因为这样可以通过调用fgets() 读取整行并在内存中使用sscanf()strtok() 解析该行

标签: c file text


【解决方案1】:

scanf() 系列函数不关心换行,因此如果要处理行,则需要先读取行,然后使用sscanf() 处理行。 scanf() 系列函数还可以互换处理空白——空格、制表符、换行符等。使用制表符作为分隔符很好,但空白也可以。显然,如果您一次读取和处理一行,则换行不会真正影响扫描。

int lottery[100][5];
int line;
char buffer[4096];

for (line = 0; fgets(buffer, sizeof(buffer), stdin) != 0 && line < 100; line++)
{
    if (sscanf(buffer, "%d %d %d %d %d", &lottery[line][0], &lottery[line][1],
               &lottery[line][2], &lottery[line][3], &lottery[line][4]) != 5)
    {
        fprintf(stderr, "Faulty line: [%s]\n", line);
        break;
    }
}

这会在 EOF、太多行和错误行(不是以 5 个数字开头的行;如果您愿意,可以在循环中检查它们的值等)停止 - 但是您需要运行哪些测试?)。如果你想验证空格分隔符,你必须更加努力。

也许您只想测试 5 个数字后的空格和换行符;这有点棘手(可以做到;在sscanf() 中查找%n 转换规范)。

【讨论】:

  • 次要:建议line &lt; 100 &amp;&amp; fgets(buffer, ...不要在100行之后阅读和丢弃输入..
  • @chux:有趣的一点。这可能取决于文件中是否应该正好有 100 行(标准输入);如果是这种情况,则在检查是否有空间之前,它会到达 EOF。如果您不介意要读取更多数据,那么您首先检查索引的权利会更好。正如你所说的“次要”,你可以用任何一种方式提出论点——回想起来,在输入之前检查索引可能是更好的总体安排。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 2015-01-22
  • 1970-01-01
相关资源
最近更新 更多