标题:对输入的*.txt文件进行处理:在两行之间插入若干行(行数不确定),并在插入 ...
只看楼主
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:1 
代碼就是這個樣子。注意:這是C++。

程序代码:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include <cmath>
#include "tools.h"

struct Point
{
    double X;
    double Y;
    double Z;

    Point() : X(0), Y(0), Z(0) {};

    std::string ToString(void)
    {
        char buffer[81];
        sprintf_s(buffer, "X%-10.4f Y%-10.4f Z%-10.4f", X, Y, Z);
        return std::string(buffer);
    }

    static double Distance(const Point& p1, const Point& p2)
    {
        return sqrt(pow(p2.X - p1.X, 2) + pow(p2.Y - p1.Y, 2) + pow(p2.Z - p1.Z, 2));
    }
};

// 顯示程序使用幫助
void Show_Help(const std::string command_name)
{
    printf_s("程序格式:\n");
    printf_s("%s <輸入文件名> <輸出文件名>\n", command_name.c_str());
}

// 讀入文件數據
std::vector<Point> Load_Data(const char* filename)
{
    std::vector<Point> data;

    FILE* file;
    if (fopen_s(&file, filename, "rt") == 0)
    {
        char buffer[1024];
        Point point;
        while (fgets(buffer, _countof(buffer), file) != NULL)
        {
            const char* p;
            double x, y, z;
            p = strchr(buffer, 'X');
            if (p && (sscanf_s(p + 1, "%lf", &x) == 1))
            {
                point.X = x;
            }
            p = strchr(buffer, 'Y');
            if (p && (sscanf_s(p + 1, "%lf", &y) == 1))
            {
                point.Y = y;
            }
            p = strchr(buffer, 'Z');
            if (p && (sscanf_s(p + 1, "%lf", &z) == 1))
            {
                point.Z = z;
            }
            data.push_back(point);
        }
        fclose(file);
    }

    return data;
}

size_t Write_Data(const char* filename, std::vector<Point>& data)
{
    size_t count = 0;

    FILE* file;
    if (fopen_s(&file, filename, "wt") == 0)
    {
        while (count < data.size() - 1)
        {
            fprintf_s(file, "%s\n", data[count].ToString().c_str());
            double distance = Point::Distance(data[count + 1], data[count]);
            if ( distance > 0.1)
            {
                Point next_point = data[count];
                const int n = static_cast<int>(distance / 0.1);
                const double increase_x = (data[count + 1].X - data[count].X) / n;
                const double increase_y = (data[count + 1].Y - data[count].Y) / n;
                const double increase_z = (data[count + 1].Z - data[count].Z) / n;
                for (int i = 0; i < n - 1; ++i)
                {
                    next_point.X += increase_x;
                    next_point.Y += increase_y;
                    next_point.Z += increase_z;
                    fprintf_s(file, "%s\n", next_point.ToString().c_str());
                }
            }
            ++count;
        }
        fprintf_s(file, "%s\n", data[count].ToString().c_str());
        fclose(file);
    }

    return count;
}

// 程序主入口
int main(int argc, char* argv[])
{
    if (argc < 3)
    {
        Show_Help(GetJustFileName(argv[0]));
        Pause();
        return EXIT_FAILURE;
    }

    std::vector<Point> data = Load_Data(argv[1]);
    printf_s("輸出記錄總數: %u\n", Write_Data(argv[2], data));

    return EXIT_SUCCESS;
}

授人以渔,不授人以鱼。
2015-10-14 15:01
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
寫得比較匆忙,有些地方不是很規範,先看正確性好了,滿足要求之後,再談改進。

授人以渔,不授人以鱼。
2015-10-14 15:15
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
這個程序,佔用內存,暴發一度最大到10M,主要原因是把輸入文件全部讀入內存所致,但擴展輸出的龐大數據(從結果可見其規模高達100M)不是全部放在內存中再輸出的。觀察輸出部分是如何分階段進行以節約內存的,就能用同樣的分段步驟用於讀入。在工業上的低級機器,沒有那麼多內存,比如在運行DOS的PC上,全部內存也不過1M,所以節減內存的手段是需要考慮的。當然了,節省內存的代價是減緩運行速度,這是守恆方程式。

授人以渔,不授人以鱼。
2015-10-14 16:03
cyxcpyzc
Rank: 1
等 级:新手上路
帖 子:23
专家分:0
注 册:2013-11-26
得分:0 
回复 33楼 TonyDeng
昨晚发现我的VS2012有问题,不好意信息反馈迟了。
今天装了VS2015调试时出异常。(见图)
我这只菜鸟不知如何处理?
2015-10-15 10:44
cyxcpyzc
Rank: 1
等 级:新手上路
帖 子:23
专家分:0
注 册:2013-11-26
得分:0 
回复 33楼 TonyDeng
我把输入文件改为英文文件名,添加到资源文件。现在计算结果out.txt出来了。计算速度还挺快。
2015-10-15 14:25
cyxcpyzc
Rank: 1
等 级:新手上路
帖 子:23
专家分:0
注 册:2013-11-26
得分:0 
回复 33楼 TonyDeng
我用的控制软件是装在PC上,用USB口与外面接口板连接。现在不知文件太大时传输速率能否跟得上
我刚才用仿真软件对out.txt做了验证。路径是正确的。版主您真伟大!谢谢您!
仿真软件验证,图像参见附件视频"行走路径.mp4
行走路径.part1.rar (1.39 MB)
行走路径.part2.rar (1.39 MB)
行走路径.part3.rar (1.39 MB)
行走路径.part4.rar (1022.17 KB)
2015-10-15 15:05
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:0 
我寫的東西好像沒用到C++11,應該可以在vs2012中編譯。你出錯的動作,是怎麼做出來的?文件名用了中文?

授人以渔,不授人以鱼。
2015-10-15 17:46
cyxcpyzc
Rank: 1
等 级:新手上路
帖 子:23
专家分:0
注 册:2013-11-26
得分:0 
回复 37楼 TonyDeng
我又试了一下。

输入的原始数据文件名只能用in.txt  如果用中文或其它的英文名都会报错。
2015-10-15 20:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
得分:1 
源代码有提示用命令行参数的啊,在《项目》的调试命令行项中写参数,那是我写好的,你可以随便改。设计是在命令行窗口中使用的。

授人以渔,不授人以鱼。
2015-10-15 21:50
cyxcpyzc
Rank: 1
等 级:新手上路
帖 子:23
专家分:0
注 册:2013-11-26
得分:0 
回复 39楼 TonyDeng
谢谢您的提示!

在VS2015中虽然调试时有报警,但是生成的exe文件是可以使用的。

我在命令提示符窗口中使用(用键盘敲入命令Project_01),输入、输出文件可用任何的文件名,包括中文的。

如果直接双击Project_01.exe,窗口会闪现一下即刻关闭,不会暂停那里,给出帮助提示。

但是在VS2015中调试时要想不报错,只能把输入文命名为in.txt 并将其添加到资源文件下才不会出现异常报警。




[此贴子已经被作者于2015-10-16 09:02编辑过]

2015-10-15 23:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-458147-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.286479 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved