鱼C论坛

 找回密码
 立即注册
查看: 1176|回复: 7

[已解决]如何把含有字母数字和符号的文件,提取出数字坐标,并保存到TXT文件中

[复制链接]
发表于 2019-1-17 22:17:23 | 显示全部楼层 |阅读模式
15鱼币
有个问题困扰多天了,读取plt文件,读取方式和TXT文件相同,得出很多信息,如何能够把PU和PD后面的坐标提取出来放到一个TXT文件中
似这种
IN;
VS32,1;
VS32,2;
VS32,3;
VS32,4;
VS32,5;
VS32,6;
VS32,7;
VS32,8;
WU0;
PW0.350,1;
PW0.350,2;
PW0.350,3;
PW0.350,4;
PW0.350,5;
PW0.350,6;
PW0.350,7;
PW0.350,8;
LT;
SP1;
PU0 -1200;
PD1600 -1200;
PD1600 1200;
PD0 1200;
PD0 -1200;
SP0;
最佳答案
2019-1-17 22:17:24
#include <iostream>
#include <fstream>
#include <string>
#include <cstdint>
#include <vector>
#include <sstream>

union Data
{
        struct { int32_t vs_a; int32_t vs_b; };
        struct { double pw_a; int32_t pw_b; };
        struct { int32_t pu_a; int32_t pu_b; };
        struct { int32_t pd_a; int32_t pd_b; };
        int32_t wu;
        int32_t sp;
};

struct Info
{
        std::string id;
        Data data;
};


static int32_t StringToInteger(const std::string &num)
{
        std::stringstream ss;
        ss << num;
        int32_t result = 0;
        ss >> result;
        return result;
}

static size_t ReadInteger(std::string::const_iterator begin, std::string::const_iterator end, int32_t &dest)
{
        std::string::const_iterator i = begin;
        while(i != end && (!isdigit(*i) && *i != '-'))
                ++i;

        std::string num;
        while(i != end && (isdigit(*i) || *i == '-'))
        {
                num.push_back(*i);
                ++i;
        }

        dest = StringToInteger(num);
        return i - begin;
}

static double StringToDouble(const std::string &num)
{
        std::stringstream ss;
        ss << num;
        double result = 0;
        ss >> result;
        return result;
}

static size_t ReadDouble(std::string::const_iterator begin, std::string::const_iterator end, double &dest)
{
        std::string::const_iterator i = begin;
        while(i != end && (!isdigit(*i) && *i != '-'))
                ++i;

        std::string num;
        while(i != end && (isdigit(*i) || *i == '-' || *i == '.'))
        {
                num.push_back(*i);
                ++i;
        }

        dest = StringToDouble(num);
        return i - begin;
}

const std::string GetStatement(std::ifstream &file)
{
        std::string result;

        while(file.peek() != EOF && isspace(file.peek()))
                file.get();
        while(file.peek() != EOF && file.peek() != ';')
                result.push_back(file.get());
        if(file.peek() != EOF)
                file.get();

        return result;
}

const Info ReadStatement(const std::string &statement)
{
        Info result = {"", 0};
        std::string::const_iterator iter;
        for(iter = statement.begin(); iter != statement.end(); ++iter)
        {
                if(!isalpha(*iter))
                        break;
                result.id.push_back(*iter);
        }

        if((result.id == "IN") || (result.id == "LT"))
                ;
        else if(result.id == "WU")
                ReadInteger(iter, statement.end(), result.data.wu);
        else if(result.id == "SP")
                ReadInteger(iter, statement.end(), result.data.sp);
        else if(result.id == "VS")
        {
                iter += ReadInteger(iter, statement.end(), result.data.vs_a);
                ReadInteger(iter, statement.end(), result.data.vs_b);
        }
        else if(result.id == "PW")
        {
                iter += ReadDouble(iter, statement.end(), result.data.pw_a);
                ReadInteger(iter, statement.end(), result.data.pw_b);
        }
        else if(result.id == "PU")
        {
                iter += ReadInteger(iter, statement.end(), result.data.pu_a);
                ReadInteger(iter, statement.end(), result.data.pu_b);
        }
        else if(result.id == "PD")
        {
                iter += ReadInteger(iter, statement.end(), result.data.pd_a);
                ReadInteger(iter, statement.end(), result.data.pd_b);
        }

        return result;
}

void WriteFile(std::ofstream &file, const Info &info)
{
        if(info.id == "PU")
                file << info.data.pu_a << "," << info.data.pu_b << std::endl;
        else if(info.id == "PD")
                file << info.data.pd_a << "," << info.data.pd_b << std::endl;
}

void PrintInfo(const Info &info)
{
        if((info.id == "IN") || (info.id == "LT"))
                std::cout << info.id << ":" << std::endl;
        else if(info.id == "WU")
                std::cout << info.id << ":" << "(" << info.data.wu << ")" << std::endl;
        else if(info.id == "SP")
                std::cout << info.id << ":" << "(" << info.data.sp << ")" << std::endl;
        else if(info.id == "VS")
                std::cout << info.id << ":" << "(" << info.data.vs_a << "," << info.data.vs_b << ")" << std::endl;
        else if(info.id == "PW")
                std::cout << info.id << ":" << "(" << info.data.pw_a << "," << info.data.pw_b << ")" << std::endl;
        else if(info.id == "PU")
                std::cout << info.id << ":" << "(" << info.data.pu_a << "," << info.data.pu_b << ")" << std::endl;
        else if(info.id == "PD")
                std::cout << info.id << ":" << "(" << info.data.pd_a << "," << info.data.pd_b << ")" << std::endl;
}

int main()
{
        std::ifstream in("1.txt");
        std::vector<Info> vi;
        std::string statement;
        while(statement = GetStatement(in), in)
                vi.push_back(ReadStatement(statement));
        in.close();

        std::ofstream out("2.txt");
        for(const auto &i: vi)
        {
                PrintInfo(i);
                WriteFile(out, i);
        }
        out.close();
        return 0;
}

1.png
%%ESL(@REI1@6YGQG9H6MV3.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-1-17 22:17:24 | 显示全部楼层    本楼为最佳答案   
#include <iostream>
#include <fstream>
#include <string>
#include <cstdint>
#include <vector>
#include <sstream>

union Data
{
        struct { int32_t vs_a; int32_t vs_b; };
        struct { double pw_a; int32_t pw_b; };
        struct { int32_t pu_a; int32_t pu_b; };
        struct { int32_t pd_a; int32_t pd_b; };
        int32_t wu;
        int32_t sp;
};

struct Info
{
        std::string id;
        Data data;
};


static int32_t StringToInteger(const std::string &num)
{
        std::stringstream ss;
        ss << num;
        int32_t result = 0;
        ss >> result;
        return result;
}

static size_t ReadInteger(std::string::const_iterator begin, std::string::const_iterator end, int32_t &dest)
{
        std::string::const_iterator i = begin;
        while(i != end && (!isdigit(*i) && *i != '-'))
                ++i;

        std::string num;
        while(i != end && (isdigit(*i) || *i == '-'))
        {
                num.push_back(*i);
                ++i;
        }

        dest = StringToInteger(num);
        return i - begin;
}

static double StringToDouble(const std::string &num)
{
        std::stringstream ss;
        ss << num;
        double result = 0;
        ss >> result;
        return result;
}

static size_t ReadDouble(std::string::const_iterator begin, std::string::const_iterator end, double &dest)
{
        std::string::const_iterator i = begin;
        while(i != end && (!isdigit(*i) && *i != '-'))
                ++i;

        std::string num;
        while(i != end && (isdigit(*i) || *i == '-' || *i == '.'))
        {
                num.push_back(*i);
                ++i;
        }

        dest = StringToDouble(num);
        return i - begin;
}

const std::string GetStatement(std::ifstream &file)
{
        std::string result;

        while(file.peek() != EOF && isspace(file.peek()))
                file.get();
        while(file.peek() != EOF && file.peek() != ';')
                result.push_back(file.get());
        if(file.peek() != EOF)
                file.get();

        return result;
}

const Info ReadStatement(const std::string &statement)
{
        Info result = {"", 0};
        std::string::const_iterator iter;
        for(iter = statement.begin(); iter != statement.end(); ++iter)
        {
                if(!isalpha(*iter))
                        break;
                result.id.push_back(*iter);
        }

        if((result.id == "IN") || (result.id == "LT"))
                ;
        else if(result.id == "WU")
                ReadInteger(iter, statement.end(), result.data.wu);
        else if(result.id == "SP")
                ReadInteger(iter, statement.end(), result.data.sp);
        else if(result.id == "VS")
        {
                iter += ReadInteger(iter, statement.end(), result.data.vs_a);
                ReadInteger(iter, statement.end(), result.data.vs_b);
        }
        else if(result.id == "PW")
        {
                iter += ReadDouble(iter, statement.end(), result.data.pw_a);
                ReadInteger(iter, statement.end(), result.data.pw_b);
        }
        else if(result.id == "PU")
        {
                iter += ReadInteger(iter, statement.end(), result.data.pu_a);
                ReadInteger(iter, statement.end(), result.data.pu_b);
        }
        else if(result.id == "PD")
        {
                iter += ReadInteger(iter, statement.end(), result.data.pd_a);
                ReadInteger(iter, statement.end(), result.data.pd_b);
        }

        return result;
}

void WriteFile(std::ofstream &file, const Info &info)
{
        if(info.id == "PU")
                file << info.data.pu_a << "," << info.data.pu_b << std::endl;
        else if(info.id == "PD")
                file << info.data.pd_a << "," << info.data.pd_b << std::endl;
}

void PrintInfo(const Info &info)
{
        if((info.id == "IN") || (info.id == "LT"))
                std::cout << info.id << ":" << std::endl;
        else if(info.id == "WU")
                std::cout << info.id << ":" << "(" << info.data.wu << ")" << std::endl;
        else if(info.id == "SP")
                std::cout << info.id << ":" << "(" << info.data.sp << ")" << std::endl;
        else if(info.id == "VS")
                std::cout << info.id << ":" << "(" << info.data.vs_a << "," << info.data.vs_b << ")" << std::endl;
        else if(info.id == "PW")
                std::cout << info.id << ":" << "(" << info.data.pw_a << "," << info.data.pw_b << ")" << std::endl;
        else if(info.id == "PU")
                std::cout << info.id << ":" << "(" << info.data.pu_a << "," << info.data.pu_b << ")" << std::endl;
        else if(info.id == "PD")
                std::cout << info.id << ":" << "(" << info.data.pd_a << "," << info.data.pd_b << ")" << std::endl;
}

int main()
{
        std::ifstream in("1.txt");
        std::vector<Info> vi;
        std::string statement;
        while(statement = GetStatement(in), in)
                vi.push_back(ReadStatement(statement));
        in.close();

        std::ofstream out("2.txt");
        for(const auto &i: vi)
        {
                PrintInfo(i);
                WriteFile(out, i);
        }
        out.close();
        return 0;
}

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-1-17 22:33:26 | 显示全部楼层
得到的txt要什么样?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-1-17 22:39:27 | 显示全部楼层
ba21 发表于 2019-1-17 22:33
得到的txt要什么样?

类似这种,只去PU和PD之后的坐标的值
0 -1200
1600 -1200
1600 1200
0 1200
0 -1200
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-1-18 11:00:00 | 显示全部楼层

谢谢,功能实现了,就是C++我只了解一点,所以看起来还是比较吃力的,我用c语言写的提取出来了,这些信息,但是如何把坐标值提取出来,去除前面的PD和PU和后面的分号,就有些迷惑了
PD-1109 1207;
PD-1633 1207;
PD-1621 1249;
PD-1595 1282;
PD-1557 1315;
PD-1430 1389;
PD-1322 1448;
PD-1256 1493;
PD-1221 1531;
PD-1210 1566;
PD-1220 1599;
PD-1251 1627;
PD-1299 1645;
PD-1359 1651;
PD-1423 1645;
PD-1472 1625;
PD-1504 1594;
PD-1515 1553;
PD-1614 1559;
PD-1590 1621;
PD-1537 1665;
PD-1459 1693;
PD-1357 1702;
PD-1255 1692;
PD-1177 1662;
PD-1127 1618;
PD-1115 1593;
PD-1111 1565;
PD-1115 1536;
PD-1130 1507;
PD-1194 1446;
PD-1344 1360;
PD-1457 1298;
PD-1498 1265;
PD-1109 1265;
PU-1004 1450;
PD-997 1529;
PD-976 1591;
PD-940 1638;
PD-890 1673;
PD-826 1695;
PD-747 1702;
PD-688 1698;
PD-635 1686;
PD-592 1666;
PD-556 1640;
PD-529 1606;
PD-508 1567;
PD-494 1516;
PD-490 1450;
PD-497 1372;
PD-518 1310;
PD-554 1263;
PD-604 1228;
PD-668 1206;
PD-747 1199;
PD-849 1212;
PD-926 1250;
PD-961 1285;
PD-985 1331;
PD-1000 1386;
PD-1004 1450;
PU-905 1450;
PD-894 1349;
PD-880 1314;
PD-860 1289;
PD-809 1258;
PD-747 1249;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-1-18 14:39:26 | 显示全部楼层
C++  666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-1-18 15:54:14 | 显示全部楼层
lwd2wl 发表于 2019-1-18 11:00
谢谢,功能实现了,就是C++我只了解一点,所以看起来还是比较吃力的,我用c语言写的提取出来了,这些信息 ...
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdint.h>

typedef struct
{
        int32_t x, y;
} POINT;

static int32_t StringToInteger(const char *num)
{
        int32_t result = 0;
        sscanf(num, "%d", &result);
        return result;
}

static size_t ReadInteger(const char *statement, int32_t *dest)
{
        const char *begin = statement;
        for(; *statement; ++statement)
        {
                if(!isdigit(*statement))
                        continue;
                break;
        }

        char num[512];
        int32_t index = 0;
        while(1)
        {
                if(isdigit(*statement) || *statement == '-')
                {
                        num[index++] = *statement;
                        ++statement;
                        continue;
                }
                num[index++] = '\0';
                break;
        }

        *dest = StringToInteger(num);
        return statement - begin;
}

char GetStatement(FILE *file, char *buf)
{
        char ch;
        while(1)
        {
                ch = fgetc(file);
                if(ch != EOF && isspace(ch))
                        continue;
                if(ch != EOF)
                        ungetc(ch, file);
                break;
        }

        while(1)
        {
                ch = fgetc(file);
                if(ch != EOF && ch != ';')
                {
                        *buf++ = ch;
                        continue;
                }
                *buf++ = '\0';
                break;
        }

        return ch;
}

const POINT ReadStatement(const char *statement)
{
        for(; *statement; ++statement)
        {
                if(!isdigit(*statement))
                        continue;
                break;
        }

        POINT result = {0, 0};
        statement += ReadInteger(statement, &result.x);
        ReadInteger(statement, &result.y);
        return result;
}

int main(void)
{
        char buf[512];
        FILE *file = fopen("1.txt", "r");
        while(GetStatement(file, buf) != EOF)
        {
                POINT point = ReadStatement(buf);
                printf("(%d, %d)\n", point.x, point.y);
        }
        fclose(file);

        return 0;
}

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-1-18 16:06:55 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 06:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表