C文本文件处理 fgets读取每行数据并处理

需要解决的问题:有一个文本,每行由16个 0到f的字符组成(64bit的数字写成十六进制表示),需要统计整个文本中0到f 十六个字符的个数。

matlab做循环运算比较慢,特别在循环次数很多的时候更慢。这时候用C更有优势。按行读取文本,我采用的是fgets()函数。

#include <stdint.h>
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
#include <ctype.h>

int main(){

FILE* fp = fopen("a.txt","r");
if(fp == NULL){
  printf("Error: read file failure.\n");
  exit(-1);
}


char txt[1000] = {0};  //存储每行的字符串
uint64_t stat[16] = {0}; //统计
char sample[16] = {'0', '1', '2', '3',
                   '4', '5', '6', '7',
                   '8', '9', 'a', 'b',
                   'c', 'd', 'e', 'f'};
int i,j;
while(!feof(fp)){
  memset(txt, 0, sizeof(txt));
  fgets(txt, sizeof(txt-1), fp); //读取一行字符串
  
  if(strlen(txt) != 17) //防止出现异常行
    continue; 

  for(i = 0; i < 16; i++){
    for(j = 0; j < 16; j++){
      if(txt[i] == sample[j]
        stat[j]++;
        break;
    }
  }
}
fclose(fp);

for(i = 0; i < 16; i++){
  printf("%u\n", stat[i]);
}
}

如果是按2bit统计,那么只需要修改中间部分代码

char sample[4] = {0, 1, 2, 3};
int data, index;
for(i = 0; i < 16; i++){
  if(isdigit(txt[i])
     data = txt[i] - 48;
  else if(isupper(txt[i])
     data = txt[i] - 55;
  else 
     data = txt[i] - 87;

  index = data & 0x3;
  for(j = 0; j < 4; j++){
    if(index == sample[j]){
      stat[j]++;
      break;
    }      
  }

  index = (data & 0xc)>>2; //记得右移2位
  for(j = 0; j < 4; j++){
    if(index == sample[j]){
      stat[j]++;
      break;
    }      
  }
}

 

`fgets` 函数在 C 语言中用于从指定位置读取一行文本到缓冲区中,但它是用来处理标准输入流(如键盘)或文件的,通常不会直接用于从文件中逐行读取数据写入结构体数组。不过,我们可以使用循环结合 `fgets` 和一个临时字符串变量来实现这个功能。 假设我们有一个结构体定义,比如: ```c typedef struct { char name[50]; int age; } Person; ``` 我们可以创建一个动态大小的结构体数组,然后使用以下步骤来读取文件中的多行数据: 1. 打开文件,确保正确关闭: ```c FILE* file = fopen("filename.txt", "r"); if (file == NULL) { perror("Error opening the file"); exit(1); } ``` 2. 初始化一个结构体数组和计数器: ```c Person people[MAX_LINES]; // 假设 MAX_LINES 是一个足够大的常量 size_t count = 0; ``` 3. 使用 `fgets` 逐行读取解析每一行数据: ```c char line[100]; // 小于 fgets 的最大读取长度 while (fgets(line, sizeof(line), file)) { if (count < MAX_LINES) { // 防止溢出 sscanf(line, "%s %d", &people[count].name, &people[count].age); // 假设年龄字段是整数 count++; } else { printf("Too many lines in the file, skipping rest.\n"); break; // 文件已满,停止读取 } } fclose(file); ``` 4. 结果存储在 `people` 数组中,`count` 表示实际读取的条目数量。 这里我们使用了 `sscanf` 来解析每行字符串,`%s` 捕获名字的部分,`%d` 捕获年龄部分。如果文件中的某一行不符合预期格式(例如没有空格分隔),则可能需要进行额外的错误检查或更复杂的解析逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值