【问题标题】:How to insert string into a string by C the better way? [closed]如何以更好的方式将字符串插入到字符串中? [关闭]
【发布时间】:2019-08-19 05:18:27
【问题描述】:

我想做一些事情

char* a = "/data/cc/dd/ee/ff/1.jpg";

然后得到

char* b = "/data/cc/dd/ee/ff/json_1.json";

char *b = "/data/cc/dd/ee/1.txt";

在 Python 中这很容易,但不幸的是我必须在 C 中做到这一点。 我做了类似的事情:

Ubuntu C

char classpath[4096];
char *dirc, *basec, *bname, *dname;
find_replace(path, ".jpg", ".txt", classpath);
dirc = strdup(path);
basec = strdup(path);
dname = dirname(dirc);
bname = basename(basec);

我知道下一步应该连接dname'json_'bname 可能首先创建最终路径,例如 char ressultpath[4096]; 然后使用strcat(),但我想知道什么是使用更少内存和更快的更好方法,因为我真的不熟悉C。

【问题讨论】:

  • 请注意,strdupdirnamebasename 是在 IEEE POSIX(标准化类 Unix 操作系统的文档)中定义的特定于平台的函数,而不是 ISO C。strdup 已被在 POSIX 中使用了 30 年,但 dirnamebasename 较新;它们是在 2008 年左右的第 4 期中添加的。
  • dirname()basename() 都在 SUS 1997 中,并且可以在许多系统上更快地使用它们,就像它们在 SVR4 和 SVID 中一样。它们也被记录在POSIX 2004 中——basename()dirname()

标签: c string char


【解决方案1】:

您可以使用标准函数strrchr()(搜索字符串中字符的最后一个实例)来查找路径名中的最后一个/ 和文件名组件中的最后一个.。从这些字符的位置(如果它们存在),您可以计算路径的目录和文件名组件的起始位置和长度。然后,您可以使用 snprintf() 函数与这些起始位置和长度将您想要的文件名拼接在一起:

char classpath[4096];
const char *dir_end;
const char *name;
const char *suffix;
int dir_length;
int name_length;
int result_length;

/* Find the end of the directory component of the path, if it has one. */
dir_end = strrchr(path, '/');

if (dir_end)
{
    /* The filename starts immediately after the final / */
    name = dir_end + 1;
    /* The length of the directory component up to and including the final / */
    dir_length = dir_end - path + 1;
}
else
{
    /* No directory component, so the filename begins at the start of the path */
    name = path;
    dir_length = 0;
}

/* Find the start of the file suffix, if it has one */
suffix = strrchr(name, '.');

if (suffix)
{
    /* The length of the name not including the last . */
    name_length = suffix - name;
}
else
{
    /* No suffix at all, so the name is everything remaining */
    name_length = strlen(name);
}

result_length = snprintf(classpath, sizeof classpath, "%.*sjson_%.*s.json", dir_length, path, name_length, name);

if (result_length >= sizeof classpath)
{
    /* result was truncated */
}

【讨论】:

  • 各种长度变量最好输入size_t
  • @alk:不幸的是,%.* 可变精度说明符要求 int 被传递(并且 snprintf() 返回 int)。您可以预先测试以确保整个传递路径的长度不超过INT_MAX
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
相关资源
最近更新 更多