如何传递指向字符串的指针、指向子字符串的指针以及 return 其他内容?
How to pass the pointer to a string, pointer to a substring, and return something else?
我在一个非常有限的 MCU 上 space,而且我在 C 中以某种方式丢失了我的参考。我想要这样的格式:
int commandsubstring(char *stringaddress,char *substringaddress);
但是,我在 ASM 中执行了这个例程,因为我在 C 中遇到了一些问题并且只是想完成它。既然已经完成了,我想修复它。该函数的作用是读取 SCPI 命令。我采用 "MEASure:VOLTage:DC?" 的格式,然后递归 return 命令。在我的示例中,想要 return 子字符串的地址
MEASure:VOLTage:DC?
^ ^
我希望能够做类似的事情:
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, subcmd);
printf("%s\n", cmd);
printf("%s\n", subcmd);
然后得到
的结果
MEASure:VOLTage:DC?
VOLTage:DC?
我不确定为什么,但我在这个过程中的某个地方丢失了我的指针。在其余的代码中,我只是 return 结构,但由于这个特定部分是递归的,我想尝试一些我觉得更安全的东西,但我似乎无法正确地获得 C 并且这只是某个地方的脑洞。如有任何帮助,我们将不胜感激。
编辑
这不是关于标记化的问题,只是正确 return 同一字符串中不同位置的正确方法。
查看您提供的声明和用法示例,我认为您需要一个指向指针的指针作为第二个参数。你拥有的是一个指向字符的指针。
您所看到的很像未定义的行为:
/* Takes two pointer by value */
int commandsubstring(char *stringaddress,char *substringaddress);
void foo(void)
{
char *cmd="MEASure:VOLTage:DC?";
char *subcmd; /* an uninitialized variable, could be anything */
commandsubstring(cmd, subcmd); /* you pass an uninitilized variable in */
printf("%s\n", cmd);
printf("%s\n", subcmd); /* you use an uninitialized variable. Nothing has changed it since it was declared. */
}
你对 "the proper way to correctly return a different location in the same string" 的请求听起来像 "the way to correctly return a pointer to char in the same string"。有两种方法:您可以使用 return 值,或者使用 OUT 参数。
假设它不是 char *
,想象一下您想要某个函数的 int
。这是你 "int" 选项:
/* You want (int) from you functions */
int use_int_return_value(void);
void use_int_out_parameter(int *pint_to_result);
/* You want (char *) from you functions */
char * use_pchar_return_value(void);
void use_pchar_out_parameter(char ** pchar_to_result);
当你这样做时:
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, subcmd);
您正在将 subcmd
的 值 传递给函数。在函数内部,它可能正在为命名参数赋值,这不会更改调用函数中的变量。
最干净的处理方法是删除第二个参数和 return 有问题的指针,将其分配给 subcmd
:
char *commandsubstring(char *stringaddress);
...
subcmd = commandsubstring(cmd);
也许这个例子会有所帮助:
#include <stdio.h>
int commandsubstring(char *stringaddress,char **substringaddress)
{
char * ptr = stringaddress;
while (ptr!=0) {
if ((*ptr)==':') {
*substringaddress = ptr+1;
break;
}
ptr++;
}
return 0;
}
int main()
{
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, &subcmd);
printf("%s\n", cmd);
printf("%s\n", subcmd);
return 0;
}
假设子命令由第一个 :
标识,您可以这样做:
#include <stdio.h>
#include <string.h>
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
puts(cmd);
const char * subcmd = strchr(cmd, ':');
if (NULL == subcmd || !*(++subcmd))
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
要将其作为函数执行
#include <stdio.h>
#include <string.h>
#include <assert.h>
const char * find_subcmd(const char * cmd)
{
assert(NULL != cmd);
char * subcmd = strchr(cmd, ':');
return (NULL == subcmd || !*(++subcmd)) ?NULL :subcmd;
}
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
puts(cmd);
const char * subcmd = find_subcmd(cmd);
if (NULL == subcmd)
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
或
#include <stdio.h>
#include <string.h>
#include <assert.h>
int find_subcmd(const char * cmd, char const ** psubcmd )
{
assert(NULL != cmd);
assert(NULL != psubcmd);
char * subcmd = strchr(cmd, ':');
*psubcmd = (NULL == subcmd || !*(++subcmd)) ?NULL :subcmd;
return *psubcmd ?0 :-1;
}
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
const char * subcmd = NULL;
puts(cmd);
if (-1 == find_subcmd(cmd, &subcmd))
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
请注意,在上述任何解决方案中,subcmd
只是指向 "into" cmd
所指向的内容。没有数据被复制。
我在一个非常有限的 MCU 上 space,而且我在 C 中以某种方式丢失了我的参考。我想要这样的格式:
int commandsubstring(char *stringaddress,char *substringaddress);
但是,我在 ASM 中执行了这个例程,因为我在 C 中遇到了一些问题并且只是想完成它。既然已经完成了,我想修复它。该函数的作用是读取 SCPI 命令。我采用 "MEASure:VOLTage:DC?" 的格式,然后递归 return 命令。在我的示例中,想要 return 子字符串的地址
MEASure:VOLTage:DC?
^ ^
我希望能够做类似的事情:
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, subcmd);
printf("%s\n", cmd);
printf("%s\n", subcmd);
然后得到
的结果 MEASure:VOLTage:DC?
VOLTage:DC?
我不确定为什么,但我在这个过程中的某个地方丢失了我的指针。在其余的代码中,我只是 return 结构,但由于这个特定部分是递归的,我想尝试一些我觉得更安全的东西,但我似乎无法正确地获得 C 并且这只是某个地方的脑洞。如有任何帮助,我们将不胜感激。
编辑 这不是关于标记化的问题,只是正确 return 同一字符串中不同位置的正确方法。
查看您提供的声明和用法示例,我认为您需要一个指向指针的指针作为第二个参数。你拥有的是一个指向字符的指针。
您所看到的很像未定义的行为:
/* Takes two pointer by value */
int commandsubstring(char *stringaddress,char *substringaddress);
void foo(void)
{
char *cmd="MEASure:VOLTage:DC?";
char *subcmd; /* an uninitialized variable, could be anything */
commandsubstring(cmd, subcmd); /* you pass an uninitilized variable in */
printf("%s\n", cmd);
printf("%s\n", subcmd); /* you use an uninitialized variable. Nothing has changed it since it was declared. */
}
你对 "the proper way to correctly return a different location in the same string" 的请求听起来像 "the way to correctly return a pointer to char in the same string"。有两种方法:您可以使用 return 值,或者使用 OUT 参数。
假设它不是 char *
,想象一下您想要某个函数的 int
。这是你 "int" 选项:
/* You want (int) from you functions */
int use_int_return_value(void);
void use_int_out_parameter(int *pint_to_result);
/* You want (char *) from you functions */
char * use_pchar_return_value(void);
void use_pchar_out_parameter(char ** pchar_to_result);
当你这样做时:
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, subcmd);
您正在将 subcmd
的 值 传递给函数。在函数内部,它可能正在为命名参数赋值,这不会更改调用函数中的变量。
最干净的处理方法是删除第二个参数和 return 有问题的指针,将其分配给 subcmd
:
char *commandsubstring(char *stringaddress);
...
subcmd = commandsubstring(cmd);
也许这个例子会有所帮助:
#include <stdio.h>
int commandsubstring(char *stringaddress,char **substringaddress)
{
char * ptr = stringaddress;
while (ptr!=0) {
if ((*ptr)==':') {
*substringaddress = ptr+1;
break;
}
ptr++;
}
return 0;
}
int main()
{
char *cmd="MEASure:VOLTage:DC?";
char *subcmd;
commandsubstring(cmd, &subcmd);
printf("%s\n", cmd);
printf("%s\n", subcmd);
return 0;
}
假设子命令由第一个 :
标识,您可以这样做:
#include <stdio.h>
#include <string.h>
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
puts(cmd);
const char * subcmd = strchr(cmd, ':');
if (NULL == subcmd || !*(++subcmd))
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
要将其作为函数执行
#include <stdio.h>
#include <string.h>
#include <assert.h>
const char * find_subcmd(const char * cmd)
{
assert(NULL != cmd);
char * subcmd = strchr(cmd, ':');
return (NULL == subcmd || !*(++subcmd)) ?NULL :subcmd;
}
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
puts(cmd);
const char * subcmd = find_subcmd(cmd);
if (NULL == subcmd)
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
或
#include <stdio.h>
#include <string.h>
#include <assert.h>
int find_subcmd(const char * cmd, char const ** psubcmd )
{
assert(NULL != cmd);
assert(NULL != psubcmd);
char * subcmd = strchr(cmd, ':');
*psubcmd = (NULL == subcmd || !*(++subcmd)) ?NULL :subcmd;
return *psubcmd ?0 :-1;
}
int main(void)
{
const char * cmd = "MEASure:VOLTage:DC?";
const char * subcmd = NULL;
puts(cmd);
if (-1 == find_subcmd(cmd, &subcmd))
{
fprintf(stderr, "No sub-command found.\n");
}
else
{
puts(subcmd);
}
}
请注意,在上述任何解决方案中,subcmd
只是指向 "into" cmd
所指向的内容。没有数据被复制。