鱼C论坛

 找回密码
 立即注册
查看: 1747|回复: 2

[已解决]如何对文件中的数据进行操作?

[复制链接]
发表于 2021-4-23 18:01:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 瑶瑶无期 于 2021-4-24 17:26 编辑

我的文本文件是图中这样的俩列数据,第一列是X,第二列是Y,输入任意连续X,得出最接近的Y,如输入0.05,得出17.0,输入0.23,得出16.6.请问怎么实现?数据大概四百行。
最佳答案
2021-4-25 12:00:55
本帖最后由 yuxijian2020 于 2021-4-25 17:17 编辑

不知道你用的是c还是c++

c语言:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_LEN         500

typedef struct _Pair
{
    double key;
    double value;
} Pair;

const Pair errorPair = { -0.1, -0.1 };

//分割字符串
Pair StringSplit(char* str, char sep)
{
    int pos = -1;
    for (int i = 0; i < strlen(str); i++)
    {
        if (sep == str[i])
        {
            pos = i;
            break;
        }
    }

    if (pos == -1)
        return errorPair;

    int headLen = pos + 1;
    int tailLen = strlen(str) - pos - 1;

    char* front = (char*)malloc(headLen + 1);
    char* back = (char*)malloc(tailLen + 1);
    if (!front || !back)
        return errorPair;

    memset(front, 0, headLen + 1);
    memset(back, 0, tailLen + 1);

    memcpy(front, str, headLen);
    front[headLen] = '\0';

    memcpy(back, str + headLen, tailLen);
    back[tailLen] = '\0';

    Pair result = { 0.0, 0.0 };

    result.key = atof(front);
    result.value = atof(back);

    free(front);
    free(back);

    return result;
}
//读取文件内容,函数返回值需要free
char* ReadFile(const char* path)
{
    FILE* file;
    fopen_s(&file, path, "r");
    if (!file)
        return NULL;

    fseek(file, 0, SEEK_END);
    int length = ftell(file);

    fseek(file, 0, SEEK_SET);
    char* content = (char*)malloc(length);
    if (!content)
        return NULL;

    fread(content, sizeof(char), length, file);

    return content;
}
//返回一个申请空间的Pair指针,此函数调用后,需要free返回值
Pair* StringToPair(const char* str)
{
    Pair* result = (Pair*)malloc(MAX_LEN * sizeof(Pair));
    if (!result)
        return NULL;
    memset(result, 0, MAX_LEN * sizeof(Pair));

    int start = 0;
    int cur = 0;
    int size = strlen(str);

    for (int i = 0; i < size; i++)
    {
        if (str[i] == '\n')
        {
            char* temp = (char*)malloc(i - start + 1);
            if (!temp)
            {
                free(result);
                return NULL;
            }

            memset(temp, 0, i - start + 1);
            memcpy(temp, str + start, i - start);
            temp[i - start] = '\0';
            Pair p = StringSplit(temp, '\t');
            result[cur].key = p.key;
            result[cur].value = p.value;
            cur++;
            start = i + 1;
            free(temp);
        }
    }

    return result;
}

double FindLike(Pair* pairs, double tar)
{
    double min = 1000000.0;
    double cur = 0.0;
    Pair like = { 0.0, 0.0 };

    for (int i = 0; i < MAX_LEN; i++)
    {
        cur = fabs(pairs[i].key - tar);
        if (cur < min)
        {
            like.key = pairs[i].key;
            like.value = pairs[i].value;
            min = cur;
        }
    }

    return like.value;
}

int main()
{
    char path[] = "data.txt";
    char* content = ReadFile(path);
    Pair* pairs = StringToPair(content);
    free(content);

    double in = 0.0;
    printf_s("请输入一个小数:");
    scanf_s("%lf", &in);

    double result = FindLike(pairs, in);

    free(pairs);
    printf_s("%.1lf\n", result);

    return 0;
}

c++:
#include<iostream>
#include <fstream>
#include<string>
#include <vector>

using namespace std;

//按sep分割字符串,并转化为2个double类型组成的pair
pair<double, double> StringSplit(const string& str, const string& sep)
{
    size_t pos = str.find(sep);
    if (pos == string::npos)
        return pair<double, double>();

    string front;
    string back;
    
    front.assign(str, 0, pos);
    back.assign(str, pos + sep.size(), str.size() - pos - sep.size());

    double first = atof(front.c_str());
    double second = atof(back.c_str());

    return make_pair(first, second);
}
//读取文件并将文件内容转为 2个double类型组成的pair 的数组
//数组元素为double 和 double 组成的pair
vector<pair<double, double>> ReadFileToVector(const string& path)
{
    fstream file(path, ios::in);
    vector<pair<double, double>> dataPairs;
    string line;

    while (getline(file, line))
        dataPairs.emplace_back(StringSplit(line, "\t"));

    return dataPairs;
}
//获取用户输入,并输出
void GetInputAndPrint()
{
    //这里ReadFileToVector方法的参数是文件路径
    vector<pair<double, double>> data(ReadFileToVector("data.txt"));
    double in;
    printf_s("请输入一个小数:");
    cin >> in;
    pair<double, double> like;
    double min = 1000000.0;
    double cur = 0.0;

    //遍历数组找到最接近的值
    for (const auto& p : data)
    {
        cur = fabs(p.first - in);
        if (cur < min)
        {
            like = p;
            min = cur;
        }
    }

    printf_s("%.1lf\n", like.second);
}

int main()
{
    GetInputAndPrint();

    return 0;
}

文本数据格式

文本数据格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-4-25 12:00:55 | 显示全部楼层    本楼为最佳答案   
本帖最后由 yuxijian2020 于 2021-4-25 17:17 编辑

不知道你用的是c还是c++

c语言:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define MAX_LEN         500

typedef struct _Pair
{
    double key;
    double value;
} Pair;

const Pair errorPair = { -0.1, -0.1 };

//分割字符串
Pair StringSplit(char* str, char sep)
{
    int pos = -1;
    for (int i = 0; i < strlen(str); i++)
    {
        if (sep == str[i])
        {
            pos = i;
            break;
        }
    }

    if (pos == -1)
        return errorPair;

    int headLen = pos + 1;
    int tailLen = strlen(str) - pos - 1;

    char* front = (char*)malloc(headLen + 1);
    char* back = (char*)malloc(tailLen + 1);
    if (!front || !back)
        return errorPair;

    memset(front, 0, headLen + 1);
    memset(back, 0, tailLen + 1);

    memcpy(front, str, headLen);
    front[headLen] = '\0';

    memcpy(back, str + headLen, tailLen);
    back[tailLen] = '\0';

    Pair result = { 0.0, 0.0 };

    result.key = atof(front);
    result.value = atof(back);

    free(front);
    free(back);

    return result;
}
//读取文件内容,函数返回值需要free
char* ReadFile(const char* path)
{
    FILE* file;
    fopen_s(&file, path, "r");
    if (!file)
        return NULL;

    fseek(file, 0, SEEK_END);
    int length = ftell(file);

    fseek(file, 0, SEEK_SET);
    char* content = (char*)malloc(length);
    if (!content)
        return NULL;

    fread(content, sizeof(char), length, file);

    return content;
}
//返回一个申请空间的Pair指针,此函数调用后,需要free返回值
Pair* StringToPair(const char* str)
{
    Pair* result = (Pair*)malloc(MAX_LEN * sizeof(Pair));
    if (!result)
        return NULL;
    memset(result, 0, MAX_LEN * sizeof(Pair));

    int start = 0;
    int cur = 0;
    int size = strlen(str);

    for (int i = 0; i < size; i++)
    {
        if (str[i] == '\n')
        {
            char* temp = (char*)malloc(i - start + 1);
            if (!temp)
            {
                free(result);
                return NULL;
            }

            memset(temp, 0, i - start + 1);
            memcpy(temp, str + start, i - start);
            temp[i - start] = '\0';
            Pair p = StringSplit(temp, '\t');
            result[cur].key = p.key;
            result[cur].value = p.value;
            cur++;
            start = i + 1;
            free(temp);
        }
    }

    return result;
}

double FindLike(Pair* pairs, double tar)
{
    double min = 1000000.0;
    double cur = 0.0;
    Pair like = { 0.0, 0.0 };

    for (int i = 0; i < MAX_LEN; i++)
    {
        cur = fabs(pairs[i].key - tar);
        if (cur < min)
        {
            like.key = pairs[i].key;
            like.value = pairs[i].value;
            min = cur;
        }
    }

    return like.value;
}

int main()
{
    char path[] = "data.txt";
    char* content = ReadFile(path);
    Pair* pairs = StringToPair(content);
    free(content);

    double in = 0.0;
    printf_s("请输入一个小数:");
    scanf_s("%lf", &in);

    double result = FindLike(pairs, in);

    free(pairs);
    printf_s("%.1lf\n", result);

    return 0;
}

c++:
#include<iostream>
#include <fstream>
#include<string>
#include <vector>

using namespace std;

//按sep分割字符串,并转化为2个double类型组成的pair
pair<double, double> StringSplit(const string& str, const string& sep)
{
    size_t pos = str.find(sep);
    if (pos == string::npos)
        return pair<double, double>();

    string front;
    string back;
    
    front.assign(str, 0, pos);
    back.assign(str, pos + sep.size(), str.size() - pos - sep.size());

    double first = atof(front.c_str());
    double second = atof(back.c_str());

    return make_pair(first, second);
}
//读取文件并将文件内容转为 2个double类型组成的pair 的数组
//数组元素为double 和 double 组成的pair
vector<pair<double, double>> ReadFileToVector(const string& path)
{
    fstream file(path, ios::in);
    vector<pair<double, double>> dataPairs;
    string line;

    while (getline(file, line))
        dataPairs.emplace_back(StringSplit(line, "\t"));

    return dataPairs;
}
//获取用户输入,并输出
void GetInputAndPrint()
{
    //这里ReadFileToVector方法的参数是文件路径
    vector<pair<double, double>> data(ReadFileToVector("data.txt"));
    double in;
    printf_s("请输入一个小数:");
    cin >> in;
    pair<double, double> like;
    double min = 1000000.0;
    double cur = 0.0;

    //遍历数组找到最接近的值
    for (const auto& p : data)
    {
        cur = fabs(p.first - in);
        if (cur < min)
        {
            like = p;
            min = cur;
        }
    }

    printf_s("%.1lf\n", like.second);
}

int main()
{
    GetInputAndPrint();

    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-4-25 20:29:27 | 显示全部楼层

回帖奖励 +5 鱼币

楼上代码知识点比效深,给你搞个简单的。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int GetSplitIndex(char buf[])
{
        int i;
        
        i=0;
        while(buf[i]!=9 && buf[i]!=32)
        {
                i++;
        }

        return i;
}

double GetResult(double num, double c1[], double c2[])
{
        int i;
        double current = 0.0, min=1000000.0, tmp = -1;

        i=0;
        while( c2[i] != 0)
        {
                current = fabs(c1[i] - num);
                if(current<min)
                {
                        tmp = c2[i];
                        min = current;
                }
                
                i++;
        }
        return tmp;
}


int main()
{
        FILE *fp = NULL;
        double c1[1024]={0}, c2[1024]={0}, in;
        char buf[255] = {'\0'};
        int i, index;

        // 读取文件 把第一列保存在c1 第二列保存在c2
        fp = fopen("D:\\Users\\Administrator\\Desktop\\ctest\\Debug\\readme.txt", "r");
        if(fp==NULL)
        {
                printf("文件打开失败~!\n");
                return 0;
        }

        i = 0;

        while( fgets(buf, 255, fp) != NULL )
        {
                index = GetSplitIndex(buf); // 取得 2列中间 以 TABLE 或 空格 分割符的第一次出现的位置
                buf[index] = '\0';
                c1[i] = atof(buf); // 把字符串转为double保存起来
                c2[i] = atof(&buf[index+1]); // 把字符串转为double保存起来
                
                i++;
        }

        fclose(fp);


        // 循环获取用户输入
        while(scanf("%lf", &in)!=0) // 输入非数字 退出
        {
                printf("%f\n", GetResult(in, c1, c2)); 
        }

        
        return 0; 
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-14 15:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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