【问题标题】:Need Help Manipulating a String / Pointer in C需要帮助在 C 中操作字符串/指针
【发布时间】:2014-05-26 05:00:28
【问题描述】:

基本上我有这样的东西(这是一个工作序列):

    char *command; // pointer to transmit buffer

    command = "RST; ISET 0.10A; VSET 0.00V; OUT OFF\r";
    transmit_command(PORT, command, 0);

从概念上讲,我希望能够灵活地以如下方式更新命令:

    float = current_setting;
    float = voltage_setting;

    command = "RST; ISET " + current_setting + "A; VSET " + voltage_setting + "V; OUT OFF\r":
    transmit_command(PORT, command, 0);

我对 C 语言中的指针操作不太了解,所以我的实验没有运气。我尝试了 strcpy、strcat 和 sprintf,但我的代码崩溃了,因为我认为这是因为 command 只是一个指针。

任何帮助将不胜感激。

【问题讨论】:

  • 确实,您的sprintf 代码正是您所需要的。向我们展示这一点。您可能只需要分配一个目标缓冲区,例如char buffer[128]。你可以做一个简单的堆栈分配。
  • 如果您真的需要空间,并且您将始终准确地以这四个字符(个位、小数点、十分位和百位)报告电流和电压,您无需使用大缓冲区,只需用已经填充的大部分内容覆盖字符串数组。
  • 此外,仅针对这种情况滚动您自己的代码可能会让您省略printf() 和弟兄们的代码,而且运行速度更快。

标签: c string pointers concatenation


【解决方案1】:

在 C 中,字符串实际上是以 \0 字符结尾的字符数组。所以基本上,字符串操作在 C 中很糟糕,因为你不能简单地将字符串相加。

正如您猜对的那样,您的问题之一是您没有声明一个数组来放置您的字符。您的第一个示例有效,因为指针指向用于将常量保存在内存中的字符数组。

首先,您已经声明了一个数组来包含您的字符串。如果你不是很困难,你可以简单地用char command[100];之类的东西来矫枉过正。

然后,在您的情况下,您可以使用sprintf 函数。它的工作方式与printf 类似,但它会将结果放在一个字符数组(字符串)中。

这样的事情应该可以工作:

float current_setting = [whatever];
float voltage_setting = [whatever];

char command[100];

sprintf(command, "RST; ISET; %fA; VSET %fV;OUT OFF\r", current_setting, voltage_setting);

command = "RST; ISET " + current_setting + "A; VSET " + voltage_setting + "V; OUT OFF\r":
transmit_command(PORT, command, 0);

一句警告:确保你为你的字符串声明了一个足够大的数组。不声明(或动态分配)足够大的内存区域会导致损坏、崩溃和漏洞,因为字符串函数(如sprintf从不检查数组是否足够大(在事实上,他们不能!)

【讨论】:

  • 非常感谢您的意见,我不同意。
  • 谢谢!它似乎正在工作。我之前做过类似的事情,但似乎我错过了一些东西,因为它一直在崩溃。
  • 好像你从来没有听说过snprintf() 和其他人。
  • @Deduplicator 不,尽管在 C 领域工作了多年。 :p 无论如何,虽然绝对安全(没有溢出的风险,如果你正确使用它)。它仍然可能导致错误。
  • 看起来 C 不适合你,因为 C 没有安全网,有许多明确的未定义行为领域。 (顺便说一句:给我找一个真实世界的语言和实现,没有任何警告)
【解决方案2】:

在许多 *nix 系统上,您可以使用 asprintf(),它使用 malloc 分配自己的内存来存储结果字符串。 (你应该在完成后释放()字符串,以免造成内存泄漏):

...
char *command = NULL;
float = current_setting;
float = voltage_setting;


asprintf(&command, "RST; ISET %fA; VSET %fV; OUT OFF\r ",
        current_setting, 
        voltage_setting
        );

transmit_command(PORT, command, 0);

if(command)
    free(command);

...

【讨论】:

  • 根据上下文,我认为这个用户在嵌入式系统上。他们可能仍在使用 *nix,但它不会指望它
  • 这本来不错,但我在 windows 环境中
【解决方案3】:

比我以前的答案更便携...(如果您没有 asprintf() 的话,这是一个很好的替代品...)

...
char *command = NULL;
size_t commandLength;
float = current_setting;
float = voltage_setting;

commandLength = snprintf(NULL, 0, "RST; ISET %fA; VSET %fV; OUT OFF\r ",
        current_setting, 
        voltage_setting
        );

command=malloc(commandLength + 1);

snprintf(&command, commandLength + 1, "RST; ISET %fA; VSET %fV; OUT OFF\r ",
    current_setting, 
    voltage_setting
    );

transmit_command(PORT, command, 0);

if(command)
    free(command);

...

【讨论】:

  • 谢谢!我会在星期一在我的系统上试一试
【解决方案4】:

为了一件事,将 'char *command' 变成 'char command[38]'。然后你可以使用 strcpy( command,"RST; ISET 0.10A; VSET 0.00V; OUT OFF\r" );也就是说,当然,假设您知道您的字符串不会超过 37 个字符(加上空终止符),请务必在文件顶部添加#include。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 2017-04-14
    • 2011-07-20
    • 2013-12-13
    • 1970-01-01
    • 2021-10-13
    • 2010-11-10
    • 1970-01-01
    相关资源
    最近更新 更多