【问题标题】:C fscanf complex formatC fscanf 复杂格式
【发布时间】:2017-09-25 16:59:49
【问题描述】:

我正在尝试从 C 中的文件中读取此文本。假设这是文件 Input.txt

This is a description which can be up to 1024 characters long
First
Second
Thrid   Option  This is a description for third
Fourth

我要读FirstSecondThirdFourth这4个字,剩下的就是丢弃。我有这个问题的解决方案,但我不明白它为什么起作用:

char string[1024];
char words[4][256]; 
FILE *in = fopen("Input.txt", "r");

// Catch first line
fgets(string, 1024, in);

for(int i = 0; i < 4; i++){
    fscanf(in, "%255s[^\n]\n", words[i]);
    fscanf(in, "%*[^\n]\n");
}

输入文件应为特殊格式。

  • 第一行是描述,最长可达 1024 个字符。
  • 第 2 到 5 行始终采用以下格式:“Word tab Option tab Description ”。 Word 是必需的,Option 和 Description 是可选的(例如,参见 Input.txt)

如果您能解释一下格式字符串的不同组成部分、它们的工作原理以及整个解决方案的工作原理,我将不胜感激。

(我也找不到任何关于 fscanf 格式如何工作的具体信息,如果有人可以给我一个参考,我会很高兴)

【问题讨论】:

  • "%255s[^\n]\n""%255s" 之后查找[。奇怪的代码。
  • fgets() 的效果会在第一行正好是其最大 1024 个字符(或者更长)时让您感到惊讶。
  • @chux 我认为%255s[^\n] 会读取所有字符,但不会读取\n,因为^
  • 我也愿意寻求更好的解决方案(最好有解释)
  • 不,@Codey。 %255s 跳过前导空白,然后将最多 255 个非空白字符读取到提供的数组中。之后[^\n],指示scanf 读取和使用文字字符[^、任意运行的空格和文字字符]。通常,尝试读取第一个 [ 将导致匹配失败。您的意思可能是%255s%*[^\n]%*c,它更好,但可能不如使用fgets() 读取整行。

标签: c format scanf format-string


【解决方案1】:

“以及为什么整个解决方案有效”IMO,在一般情况下,它没有。

2 个fscanf(in, ... 格式中的第2 个'\n' 使这成为一个弱解决方案。 '\n' 将扫描任意数量的换行符以及任何空白。最好继续使用fgets(string, ...),然后使用sscanf(string, ...)

"%255s[^\n]\n""%255s" 之后查找[。奇怪的代码。 @John Bollinger


相反

char string[1024+1+1];  // increase for the \n and the \0
char words[4][256]; 
FILE *in = fopen("Input.txt", "r");

// Catch first line
// fgets(string, 1024, in);
fgets(string, sizeof string, in);

// "%255s" 
// scan over yet do not save leading white-space
// scan and save up to 255 non-white-space characters.
// Append a null character to form a string
for(int i = 0; i < 4 &&  fgets(string, sizeof string, in); i++ ){
    if (sscanf(string, "%255s", words[i]) != 1) {
      words[i][0] = '\0'; // If line was all white-sapce
    }
    puts(words[i]);
}

【讨论】:

  • 我刚刚复制了代码并尝试了它,但它给了我一些奇怪的输出:�$���!-
  • @Codey 代码更正为if (sscanf(string, "%255s", words[i])...
  • 现在完美了!但我仍然不明白为什么。所以 fgets 读取整行。 sscanf 是否再次读取该行并“过滤”它?
  • @Codey 差不多。 fgets() 读取 line 并将结果保存为 string[] 中的 stringsscanf(string, "%255s", words[i]) 然后解析该 string(不是文件的行),将初始的非空白字符保存到 words[i] 作为另一个 string
  • 好的,知道了。谢谢你的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多