解析具有多个空行和额外空格的文件时出现问题

时间:2014-11-20 03:44:07

标签: c parsing newline whitespace strtok

以下是我要解析的文件的一部分:

flr2941 flr2822 flr118 flr833 flr2283 flr256 flr232
flr610 wrn448 flr1541 wrn104 wrn443 flr2680 wrn312 flr360

flr1875 flr1449 wrn456 flr549
flr297
flr122 flr2034 wrn247 wrn99 flr549 flr1606 wrn70 flr405 flr2167 wrn18 flr1976 wrn203
flr2350 flr297 flr1662 flr1747 wrn312
flr987 wrn111 flr1935
flr1552 wrn202 flr549 wrn458 flr2822 flr2900
flr1854 wrn104 flr117 flr2941
flr117 flr286 flr1454
flr2935 flr2118
 flr1662 flr2936 flr1388 wrn472 wrn19 flr117
flr1971 flr1382 flr117 wrn472 flr878 wrn203 flr662 flr1381 wrn124 flr424

flr2315 wrn70 flr2910 flr1661 flr2118 flr302
 flr1455 flr795
flr700 flr1655 wrn479 flr117

我正在尝试打印出" flrXYZ"或" wrnXYZ"表明我已经成功解析了每个文件中的单词。代码是:

/* Loop through each line in the file*/
    while(fgets(buffer, sizeof(buffer), file) != NULL) {
        /* Slice each word and if not a "\n", print it */
        tempToken = strtok(buffer, " ");
        while(tempToken != NULL) {
            stringLength = strlen(tempToken);
            printf("%s Count: %d\n", tempToken, stringLength);
            tempToken = strtok(NULL, " ");
        }
    }

我为每个令牌添加了一个计数,看看发生了什么,我得到了一些有趣的结果,但我似乎无法准确找出问题所在。这是命令行的一段随机输出(数据文件长约45,000行):

wrn70 Count: 5
flr255
 Count: 7

 Count: 1
flr1857
 Count: 8
flr2941
 Count: 8
flr2404
 Count: 8
wrn477 Count: 6

 Count: 1
flr549
 Count: 7
flr117 Count: 6
flr351 Count: 6
flr1854
 Count: 8

 Count: 1

我想要做的一个重点是这个文件有随机区域,其中有额外的换行符和空格。如何解析文件以忽略任何多余的空格或换行符?

3 个答案:

答案 0 :(得分:3)

在对\n的两次调用中,在分隔符参数中添加换行符strtok()

tempToken = strtok(buffer, " \n");

请记住,fgets()在其读取的行中包含换行符,并且strtok()被告知要在空格上拆分,因此换行符包含在单词中。


  

我无法完全理解strtok()函数如何检测连续的空格或换行符。这是说白色空间和换行符都是分隔符?

调用是说空白或换行(与空格不同; isblank()识别空格' '和标签'\t'; isspace()识别表单Feed '\f',回车'\r',换行符'\n'和垂直标签'\v'以及空格和制表符)标记strtok()所属标记的结尾认识。 strtok()被定义为将分隔符中的多个字符视为等同于一个字符。并且记住strtok()通过在标记的末尾写入空字节'\0'来破坏输入字符串,并且使用分隔符进行删除,这样你就无法分辨出分隔符是什么,除非你已经复制了分隔符。字符串或类似的东西。

您可以阅读strtok()的规范,了解它应该做什么。

答案 1 :(得分:2)

我认为Jonathan Leffler's answer会解决您的问题。

但是你的数据文件中的换行符实际上是什么意思吗?

如果没有,并且您只对一个接一个地检索字母数字标记感兴趣,那么使用fscanf()代替它会更有意义。这将使您的代码更紧凑和可读。 ("%s"格式字符串隐式忽略所有空格字符。)

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

int main() {
  FILE *file;
  char buffer[100];
  int stringLength;
  file = fopen("my_data.dat","r");
  while (fscanf(file,"%99s", buffer) != EOF) {
    stringLength = strlen(buffer);
    printf("%s Count: %d\n", buffer, stringLength);
  }
  fclose(file);
  return 0;
}

答案 2 :(得分:0)

对于strtok而不是只通过空间添加甚至&#39; \ n&#39;即,让第二个参数成为&#34; \ n&#34 ;.因为只有空格作为分隔符,所以你甚至可以将换行符作为解析后的字符串。如果两个单词之间有很多空格和许多换行符,它就可以正常工作。