gpt4 book ai didi

c - 这是 C 的好替代品吗?

转载 作者:太空宇宙 更新时间:2023-11-04 00:16:01 24 4
gpt4 key购买 nike

另见 C Tokenizer


这是我为 C 编写的快速 substr()(是的,需要将变量初始化移动到函数的开头等,但你明白了)

我见过许多 substr() 的“智能”实现,它们是简单的一个线性调用 strncpy()!

它们都是错误的(strncpy 不保证空终止,因此调用可能不会产生正确的子字符串!)

这里有更好的东西吗?

找出错误!

char* substr(const char* text, int nStartingPos, int nRun)
{
char* emptyString = strdup(""); /* C'mon! This cannot fail */

if(text == NULL) return emptyString;

int textLen = strlen(text);

--nStartingPos;

if((nStartingPos < 0) || (nRun <= 0) || (textLen == 0) || (textLen < nStartingPos)) return emptyString;

char* returnString = (char *)calloc((1 + nRun), sizeof(char));

if(returnString == NULL) return emptyString;

strncat(returnString, (nStartingPos + text), nRun);

/* We do not need emptyString anymore from this point onwards */

free(emptyString);
emptyString = NULL;

return returnString;
}


int main()
{
const char *text = "-2--4--6-7-8-9-10-11-";

char *p = substr(text, -1, 2);
printf("[*]'%s' (\")\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 1, 2);
printf("[*]'%s' (-2)\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 3, 2);
printf("[*]'%s' (--)\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 16, 2);
printf("[*]'%s' (10)\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 16, 20);
printf("[*]'%s' (10-11-)\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 100, 2);
printf("[*]'%s' (\")\n", ((p == NULL) ? "<NULL>" : p));
free(p);

p = substr(text, 1, 0);
printf("[*]'%s' (\")\n", ((p == NULL) ? "<NULL>" : p));
free(p);

return 0;
}

Output :

[*]'' (")
[*]'-2' (-2)
[*]'--' (--)
[*]'10' (10)
[*]'10-11-' (10-11-)
[*]'' (")
[*]'' (")

最佳答案

你的函数看起来很复杂,而本应是一个简单的操作。一些问题是(并非所有这些都是错误):

  • strdup() 和其他内存分配函数可能失败,您应该考虑到所有可能的问题。
  • 仅在需要时分配资源(在本例中为内存)。
  • 您应该能够区分错误和有效字符串。目前,您不知道 malloc()substr ("xxx",1,1) 失败还是正在工作的 substr ("xxx",1,0) 生成一个空字符串。
  • 您不需要 calloc() 无论如何都将要覆盖的内存。
  • 所有无效参数都应导致错误或强制转换为有效参数(您的 API 应记录具体参数)。
  • 释放后不需要将局部 emptyString 设置为 NULL - 它会在函数返回时丢失。
  • 您不需要使用 strncat() - 您应该在进行任何复制之前知道可用的大小和内存,以便您可以使用(大多数可能)更快 memcpy()
  • 您使用 base-1 而不是 base-0 作为字符串偏移量违背了 C 的原则。

下面的部分是我要做的(我更喜欢负值的 Python 习语从字符串的末尾开始计数,但我保留了长度而不是结束位置)。

char *substr (const char *inpStr, int startPos, int strLen) {
/* Cannot do anything with NULL. */

if (inpStr == NULL) return NULL;

/* All negative positions to go from end, and cannot
start before start of string, force to start. */

if (startPos < 0)
startPos = strlen (inpStr) + startPos;
if (startPos < 0)
startPos = 0;

/* Force negative lengths to zero and cannot
start after end of string, force to end. */

if (strLen < 0)
strLen = 0;
if (startPos >strlen (inpStr))
startPos = strlen (inpStr);

/* Adjust length if source string too short. */

if (strLen > strlen (&inpStr[startPos]))
strLen = strlen (&inpStr[startPos]);

/* Get long enough string from heap, return NULL if no go. */

if ((buff = malloc (strLen + 1)) == NULL)
return NULL;

/* Transfer string section and return it. */

memcpy (buff, &(inpStr[startPos]), strLen);
buff[strLen] = '\0';

return buff;
}

关于c - 这是 C 的好替代品吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/874015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com