鱼C论坛

 找回密码
 立即注册
查看: 1700|回复: 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语言:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>

  5. #define MAX_LEN         500

  6. typedef struct _Pair
  7. {
  8.     double key;
  9.     double value;
  10. } Pair;

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

  12. //分割字符串
  13. Pair StringSplit(char* str, char sep)
  14. {
  15.     int pos = -1;
  16.     for (int i = 0; i < strlen(str); i++)
  17.     {
  18.         if (sep == str[i])
  19.         {
  20.             pos = i;
  21.             break;
  22.         }
  23.     }

  24.     if (pos == -1)
  25.         return errorPair;

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

  28.     char* front = (char*)malloc(headLen + 1);
  29.     char* back = (char*)malloc(tailLen + 1);
  30.     if (!front || !back)
  31.         return errorPair;

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

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

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

  38.     Pair result = { 0.0, 0.0 };

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

  41.     free(front);
  42.     free(back);

  43.     return result;
  44. }
  45. //读取文件内容,函数返回值需要free
  46. char* ReadFile(const char* path)
  47. {
  48.     FILE* file;
  49.     fopen_s(&file, path, "r");
  50.     if (!file)
  51.         return NULL;

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

  54.     fseek(file, 0, SEEK_SET);
  55.     char* content = (char*)malloc(length);
  56.     if (!content)
  57.         return NULL;

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

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

  68.     int start = 0;
  69.     int cur = 0;
  70.     int size = strlen(str);

  71.     for (int i = 0; i < size; i++)
  72.     {
  73.         if (str[i] == '\n')
  74.         {
  75.             char* temp = (char*)malloc(i - start + 1);
  76.             if (!temp)
  77.             {
  78.                 free(result);
  79.                 return NULL;
  80.             }

  81.             memset(temp, 0, i - start + 1);
  82.             memcpy(temp, str + start, i - start);
  83.             temp[i - start] = '\0';
  84.             Pair p = StringSplit(temp, '\t');
  85.             result[cur].key = p.key;
  86.             result[cur].value = p.value;
  87.             cur++;
  88.             start = i + 1;
  89.             free(temp);
  90.         }
  91.     }

  92.     return result;
  93. }

  94. double FindLike(Pair* pairs, double tar)
  95. {
  96.     double min = 1000000.0;
  97.     double cur = 0.0;
  98.     Pair like = { 0.0, 0.0 };

  99.     for (int i = 0; i < MAX_LEN; i++)
  100.     {
  101.         cur = fabs(pairs[i].key - tar);
  102.         if (cur < min)
  103.         {
  104.             like.key = pairs[i].key;
  105.             like.value = pairs[i].value;
  106.             min = cur;
  107.         }
  108.     }

  109.     return like.value;
  110. }

  111. int main()
  112. {
  113.     char path[] = "data.txt";
  114.     char* content = ReadFile(path);
  115.     Pair* pairs = StringToPair(content);
  116.     free(content);

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

  120.     double result = FindLike(pairs, in);

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

  123.     return 0;
  124. }
复制代码


c++:
  1. #include<iostream>
  2. #include <fstream>
  3. #include<string>
  4. #include <vector>

  5. using namespace std;

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

  12.     string front;
  13.     string back;
  14.    
  15.     front.assign(str, 0, pos);
  16.     back.assign(str, pos + sep.size(), str.size() - pos - sep.size());

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

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

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

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

  43.     //遍历数组找到最接近的值
  44.     for (const auto& p : data)
  45.     {
  46.         cur = fabs(p.first - in);
  47.         if (cur < min)
  48.         {
  49.             like = p;
  50.             min = cur;
  51.         }
  52.     }

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

  55. int main()
  56. {
  57.     GetInputAndPrint();

  58.     return 0;
  59. }
复制代码

文本数据格式

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

使用道具 举报

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

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

c语言:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>

  5. #define MAX_LEN         500

  6. typedef struct _Pair
  7. {
  8.     double key;
  9.     double value;
  10. } Pair;

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

  12. //分割字符串
  13. Pair StringSplit(char* str, char sep)
  14. {
  15.     int pos = -1;
  16.     for (int i = 0; i < strlen(str); i++)
  17.     {
  18.         if (sep == str[i])
  19.         {
  20.             pos = i;
  21.             break;
  22.         }
  23.     }

  24.     if (pos == -1)
  25.         return errorPair;

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

  28.     char* front = (char*)malloc(headLen + 1);
  29.     char* back = (char*)malloc(tailLen + 1);
  30.     if (!front || !back)
  31.         return errorPair;

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

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

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

  38.     Pair result = { 0.0, 0.0 };

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

  41.     free(front);
  42.     free(back);

  43.     return result;
  44. }
  45. //读取文件内容,函数返回值需要free
  46. char* ReadFile(const char* path)
  47. {
  48.     FILE* file;
  49.     fopen_s(&file, path, "r");
  50.     if (!file)
  51.         return NULL;

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

  54.     fseek(file, 0, SEEK_SET);
  55.     char* content = (char*)malloc(length);
  56.     if (!content)
  57.         return NULL;

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

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

  68.     int start = 0;
  69.     int cur = 0;
  70.     int size = strlen(str);

  71.     for (int i = 0; i < size; i++)
  72.     {
  73.         if (str[i] == '\n')
  74.         {
  75.             char* temp = (char*)malloc(i - start + 1);
  76.             if (!temp)
  77.             {
  78.                 free(result);
  79.                 return NULL;
  80.             }

  81.             memset(temp, 0, i - start + 1);
  82.             memcpy(temp, str + start, i - start);
  83.             temp[i - start] = '\0';
  84.             Pair p = StringSplit(temp, '\t');
  85.             result[cur].key = p.key;
  86.             result[cur].value = p.value;
  87.             cur++;
  88.             start = i + 1;
  89.             free(temp);
  90.         }
  91.     }

  92.     return result;
  93. }

  94. double FindLike(Pair* pairs, double tar)
  95. {
  96.     double min = 1000000.0;
  97.     double cur = 0.0;
  98.     Pair like = { 0.0, 0.0 };

  99.     for (int i = 0; i < MAX_LEN; i++)
  100.     {
  101.         cur = fabs(pairs[i].key - tar);
  102.         if (cur < min)
  103.         {
  104.             like.key = pairs[i].key;
  105.             like.value = pairs[i].value;
  106.             min = cur;
  107.         }
  108.     }

  109.     return like.value;
  110. }

  111. int main()
  112. {
  113.     char path[] = "data.txt";
  114.     char* content = ReadFile(path);
  115.     Pair* pairs = StringToPair(content);
  116.     free(content);

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

  120.     double result = FindLike(pairs, in);

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

  123.     return 0;
  124. }
复制代码


c++:
  1. #include<iostream>
  2. #include <fstream>
  3. #include<string>
  4. #include <vector>

  5. using namespace std;

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

  12.     string front;
  13.     string back;
  14.    
  15.     front.assign(str, 0, pos);
  16.     back.assign(str, pos + sep.size(), str.size() - pos - sep.size());

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

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

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

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

  43.     //遍历数组找到最接近的值
  44.     for (const auto& p : data)
  45.     {
  46.         cur = fabs(p.first - in);
  47.         if (cur < min)
  48.         {
  49.             like = p;
  50.             min = cur;
  51.         }
  52.     }

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

  55. int main()
  56. {
  57.     GetInputAndPrint();

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

使用道具 举报

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

回帖奖励 +5 鱼币

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

  4. int GetSplitIndex(char buf[])
  5. {
  6.         int i;
  7.        
  8.         i=0;
  9.         while(buf[i]!=9 && buf[i]!=32)
  10.         {
  11.                 i++;
  12.         }

  13.         return i;
  14. }

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

  19.         i=0;
  20.         while( c2[i] != 0)
  21.         {
  22.                 current = fabs(c1[i] - num);
  23.                 if(current<min)
  24.                 {
  25.                         tmp = c2[i];
  26.                         min = current;
  27.                 }
  28.                
  29.                 i++;
  30.         }
  31.         return tmp;
  32. }


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

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

  46.         i = 0;

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

  56.         fclose(fp);


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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 21:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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