免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3697 | 回复: 9
打印 上一主题 下一主题

求助:字符串转化为整型数问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-20 12:59 |只看该作者 |倒序浏览
我想把一个文件(1.txt)中的数据(16进制) 提取出我想要的 两个字节。
现在调用一个fgets函数每次读取一行,这一行中的第27和28个数据是我想要的。
然后调用了sscanf函数读取这两个数,然后存到另外一个文件(1new.txt)中。程序如下:
红色的语句虽然可以实现这个功能但是显得很笨拙,有没有其他更好的方法实现这个功能,比如用一个循环实现红色代码部分的功能? 希望高手指教,谢谢。



#include<stdio.h>
#define FILENAME1  “1.txt.txt"
#define FILENAME2  "1new.txt"
#define MAX  1000

int main()
{
    char line[MAX];
    FILE *fp, *fd;
    int data[MAX];

    fd = fopen(FILENAME2,"w");
    if(fd == NULL)
        printf("Error creating outputfile.\n");
   
    fp = fopen(FILENAME1,"r");
    if(fp == NULL)
        printf("Error opening inputfile.\n");
       
    while( fgets(line, MAX, fp) != NULL){
        sscanf(line,"%x %x %x %x %x %x %x %x %x %x %x %x
                     %x %x %x %x %x %x %x %x %x %x %x %x
                     %x %x %x %x %x %x %x %x %x %x %x %x
                     %x %x %x %x %x %x %x %x %x %x %x %x",
                     &data[0],&data[1],&data[2],&data[3],
                     &data[4],&data[5],&data[6],&data[7],
                     &data[8],&data[9],&data[10],&data[11],
                     &data[12],&data[13],&data[14],&data[15],
                     &data[16],&data[17],&data[18],&data[19],
                     &data[20],&data[21],&data[22],&data[23],
                     &data[24],&data[25],&data[26],&data[27],
                     &data[28],&data[29],&data[30],&data[31],
                     &data[32],&data[33],&data[34],&data[35]);
      
        fprintf(fd, "%x%x\n", data[28],data[27]);
    }
    fclose(fp);
    fclose(fd);

    return 0;
}   

1.txt文件中的数据

7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 34 00 26 00 6F 00 E4 12 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 46 00 2F 00 78 00 AB B5 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 6E 00 34 00 8C 00 5C 57 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 68 00 31 00 89 00 0D 99 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 84 00 31 00 97 00 AA 39 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 54 00 30 00 7F 00 B1 72 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 66 00 37 00 88 00 06 0D 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 5C 00 28 00 83 00 3B B7 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 4C 00 2B 00 7B 00 0B AC 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 4A 00 2D 00 7A 00 42 35 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 6C 03 A6 01 0B 02 44 8C 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 42 00 2B 00 76 00 F4 5A 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 52 00 2B 00 7D 5E 00 D9 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 54 00 2F 00 7F 00 F8 BD 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 3E 00 2E 00 74 00 AC CE 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 5C 00 2E 00 83 00 A2 90 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 32 00 2C 00 6E 00 9F C4 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 3A 00 29 00 72 00 86 33 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 40 00 2C 00 75 00 CA D5 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 46 00 28 00 78 00 86 E4 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 0E 00 2B 00 5C 00 2A D2 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 2A 00 26 00 6A 00 36 77 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 28 00 25 00 69 00 F9 32 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 44 00 2E 00 77 00 61 58 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 26 00 2A 00 68 00 85 55 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 22 00 29 00 66 00 F7 EB 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 22 00 29 00 66 00 F7 EB 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 62 00 2C 00 86 00 10 2D 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 2A 00 29 00 6A 00 D8 A3 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 7A 00 32 00 92 00 9C 4C 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 72 00 2F 00 8E 00 E1 25 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 52 00 2E 00 7D 5E 00 9C 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 68 00 35 00 89 00 FC 53 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 40 00 28 00 75 00 3B 1F 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 42 00 29 00 76 00 9C B7 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 6E 00 2D 00 8C 00 8C BF 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 30 00 28 00 6D 00 7D 5D 7E
7E 42 FF FF A3 38 06 01 00 00 00 00 00 2C 86 7E  7E 42 FF FF A2 38 0A 01 00 02 00 28 00 2C 00 69 00 8E C1 7E

[ 本帖最后由 xfmy 于 2007-5-20 13:02 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-05-20 13:22 |只看该作者
既然數據這麼有規律,為什麼不直接定位?不過要執行兩次。

int d27 = strtol(line + 3 * 27,  0, 16);
int d28 = strtol(line + 3 * 28, 0, 16);

论坛徽章:
0
3 [报告]
发表于 2007-05-20 13:36 |只看该作者

回复 2楼 福瑞哈哥 的帖子

新手, 对库函数不是很熟悉... 谢谢楼上,我马上验证一下。

论坛徽章:
0
4 [报告]
发表于 2007-05-20 14:15 |只看该作者
原帖由 xfmy 于 2007-5-19 20:59 发表
我想把一个文件(1.txt)中的数据(16进制) 提取出我想要的 两个字节。
现在调用一个fgets函数每次读取一行,这一行中的第27和28个数据是我想要的。
然后调用了sscanf函数读取这两个数,然后存到另外一个文件( ...


使用sscanf的返回值,大概酱紫,没测试。

  1. int p = 0, i = 0, q;
  2. while ((q = sscanf(line + p, "%x", &data[i++]) > 0)
  3.     p += q;
复制代码

论坛徽章:
0
5 [报告]
发表于 2007-05-20 14:55 |只看该作者
先定义一个类似于这样这样的结构

typedef struct {
    char dummy[26];
    char a;
    char b;
} Info;

Info info;

然后用 fread(&info, sizeof(Info), 1, stdin) 读取, 里面的 a,  b 就是你想要的.

论坛徽章:
0
6 [报告]
发表于 2007-05-20 15:07 |只看该作者

回复 4楼 emacsnw 的帖子

验证了一下,while((q = sscanf(line +p,"%x",&data[i++])) > 0) 改为
           
            while((q = sscanf(line + p*3,"%x",&data[i++])) > 0) 可以得到想要的结果。
sscanf函数返回的是实际被转换并赋值的输入项的数目, line应该增加 p*3的 偏移量才对。

我原来就想用循环,但是没有想到过增加偏移量。谢谢你提供了思路。

论坛徽章:
0
7 [报告]
发表于 2007-05-20 18:17 |只看该作者
原帖由 xfmy 于 2007-5-19 23:07 发表
验证了一下,while((q = sscanf(line +p,"%x",&data[i++])) > 0) 改为
           
            while((q = sscanf(line + p*3,"%x",&data[i++])) > 0) 可以得到想要的结果。 ...


嗯。不过这个要假设数据都是一样长的,发现一个更好的方法:%n
       n      No  input  is  consumed.  The application shall ensure that the
              corresponding argument is a pointer to the integer  into  which
              shall be written the number of bytes read from the input so far
              by this call to the fscanf() functions. Execution of a %n  con-
              version  specification shall not increment the assignment count
              returned at the completion of execution  of  the  function.  No
              argument  shall be converted, but one shall be consumed. If the
              conversion  specification  includes  an  assignment-suppressing
              character or a field width, the behavior is undefined.


使用起来大致如下:

  1. int p = 0, i = 0, q;
  2. while (sscanf(line + p, "%x%n", &data[i++], &q) > 0)
  3.     p += q;
复制代码

论坛徽章:
0
8 [报告]
发表于 2007-05-20 19:29 |只看该作者

回复 7楼 emacsnw 的帖子

原帖由 emacsnw 于 2007-5-20 18:17 发表


嗯。不过这个要假设数据都是一样长的,发现一个更好的方法:%n


使用起来大致如下:
[code]
int p = 0, i = 0, q;
while (sscanf(line + p, "%x%n", &data[i++], &q) > 0)
     ...


嗯,这个更加通用了。 请问这个用法哪里有介绍呢? K&R的书中有没有? 想再仔细研究一下。

论坛徽章:
0
9 [报告]
发表于 2007-05-21 09:59 |只看该作者
真是服了,就取兩個值而已,還要用循環,還說要搞通用性!就這段代碼還要重用!

论坛徽章:
0
10 [报告]
发表于 2007-05-21 10:07 |只看该作者

回复 9楼 福瑞哈哥 的帖子

楼上哥们息怒,刚开始接触编程,想从这个小例子中了解到更多的用法。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP