【问题标题】:C11: how to quickly convert a char array into ints, then modify ints and update char arrayC11:如何快速将char数组转换为int,然后修改int和更新char数组
【发布时间】:2020-12-15 06:31:37
【问题描述】:

问题有两部分我不知道如何解决:

输入

用户可以输入一些输入,如12,14y15m,我需要提取两个整数和字符。现在,我只是使用:

char buffer[50];
scanf("%s", buffer);

switch (buffer[strlen(buffer)-1]) {
   // ... I use this to read the last char
}

这可以给我我必须阅读多少个整数的信息:

  • m,n 案例中的一个 -> sscanf(buffer, "%d%c", int1, c)
  • y,s,b 案例中的两个 -> sscanf(buffer, "%d,%d%c", int1, int2, c)

我需要这些数字作为我程序的核心,所以我不仅需要字符串,还需要 int 值。 问题是我在网上看到sscanf 效率低下,我需要一种快速完成这项任务的好方法。

输出

我的代码必须在一种情况下(y)修改这些数字,并保存用户输入的修改副本。例如,用户输入是1,12y,那么我必须在1,10y 中修改它并将其存储为一个字符数组,这样它就不仅仅是一个输入。 int2 的修改解释起来很长,我可以说新值会小于原始值(在我的示例中,从 12 得到 10)。我对此的唯一想法是如何创建新的 char 数组:我可以计算 int1 和 int2 长度,尝试将它们以 10 的递增幂除,直到得到 1 到 9 之间的结果。例如:

int1 = 201:
       201  no
       20.1 no
       2.01 yes
=> 3 tries, length = 3 

然后我使用 malloc。但是,我怎样才能在新的 char 数组中写入我的“输出”?例如:

input = "1,201y"
  -> int1 = 1,         int2 = 201
  -> lenght(int1) = 1, length(int2) = 2

// if the core program sets int2 = 51, then
char *out = malloc(1+2+1):
// now I have to write "1,51y" in this char array

我已经编写了“核心”程序,但现在我想改进用户输入的快速“翻译”(因为在核心程序中我需要知道它是 int1m 还是 int1n 还是 int1,int2y或 int1,int2s 或 int1,int2b 命令),我不知道如何修改用户输入以将其保存在字符串中(对于字符串,我使用动态分配的 char 数组)。只有 y 命令可以修改 int2。

我希望清楚我要做什么。

【问题讨论】:

  • 您需要更具体。预期的输入和输出是什么?
  • 你说的字符是指字符数组吗?就像 int 到 string 一样?
  • 你的问题很不清楚,也许你在找sprintf
  • 这是您的另一个问题的对应物(stackoverflow.com/questions/63586535/…),不是吗? IE。你想在这里做什么的输出是那个问题的输入?在那个问题中,事实证明阅读 scanf() 的文档非常有启发性。您是否阅读过有关 printf 和 sprintf() 的文档?
  • 顺便说一句,这里的人们通常在看到在使用tour(您没有)并最好阅读How to Ask之后提出问题时,心情会更好,更有帮助。

标签: c performance type-conversion c11


【解决方案1】:

问题是我在网上看到关于 sscanf 效率低的文章

“在线”不是一个非常值得信赖的来源。效率低下完全取决于您将函数与什么进行比较。

如果您与任何普通的 C 函数进行比较,那么 所有 stdio.h 函数的效率都非常低。就像malloc 一样。但是,打印到屏幕和等待人类用户是迄今为止该程序中最大的瓶颈,因此您可能需要重新考虑优化的原因和内容。

话虽如此,您可以通过调用 strtol 系列函数轻松推出手动专用版本的字符串到整数转换。这是一个在输入字符串中只支持 1 或 2 个整数的版本(它可以很容易地改写为使用循环):

#include <stdlib.h>

int parse_input (const char* input, int* i1, int* i2, char* ch)
{
  char* endptr=NULL;
  const char* cptr=input;
  int result;
  
  result = strtol(cptr, &endptr, 10);
  if(cptr==endptr) 
  {
    return 0; 
  }
  *i1 = result;
  
  if(*endptr != ',')
  {
    *ch = *endptr;
    return 1;
  }
  
  cptr=endptr+1;
  result = strtol(cptr, &endptr, 10);
  if(cptr==endptr)
  {
    return 0; 
  }
 
  *i2 = result;
  *ch = *endptr;
  return 2;
}

可能还需要一些额外的错误处理。这在为 x86_64 编译时提供了大约 50 条指令,不包括 strtol 调用。其中大约 20 条指令与参数堆叠和调用约定有关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2017-02-19
    相关资源
    最近更新 更多