改变字符串

发布于 2024-07-16 02:48:18 字数 1037 浏览 15 评论 0原文

我正在使用 Linux GCC c99。

我想知道最好的技术是什么。 更改字符串。 我正在使用 strstr();

我有一个名为“file.vce”的文件名,我想将扩展名更改为“file.wav”。

这是最好的方法吗:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

非常感谢您的任何建议,


我已经使用您的建议编辑了我的答案。 你还能看出还有什么问题吗?

/** Replace the file extension .vce with .wav */
void replace_file_extension(char *file_name)
{
    char *p_extension;

    /** Find the extension .vce */
    p_extension = strrchr(file_name, '.');
    if(p_extension)
    {
        strcpy(++p_extension, "wav");
    }
    else
    {
        /** Filename did not have the .vce extension */
        /** Display debug information */
    }
}

int main(void)
{
    char filename[80] = "filename.vce";

    replace_file_extension(filename);

    printf("filename: %s\n", filename);
    return 0;
}

I am using Linux GCC c99.

I am wondering what would be the best technique. To change a string. I am using strstr();

I have a filename called "file.vce" and I want to change the extension to "file.wav".

Is this the best method:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

Many thanks for any advice,


I have edited my answer using using your suggestions. Can you see anything else wrong?

/** Replace the file extension .vce with .wav */
void replace_file_extension(char *file_name)
{
    char *p_extension;

    /** Find the extension .vce */
    p_extension = strrchr(file_name, '.');
    if(p_extension)
    {
        strcpy(++p_extension, "wav");
    }
    else
    {
        /** Filename did not have the .vce extension */
        /** Display debug information */
    }
}

int main(void)
{
    char filename[80] = "filename.vce";

    replace_file_extension(filename);

    printf("filename: %s\n", filename);
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

浅紫色的梦幻 2024-07-23 02:48:18

存在一些问题:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

仅存储一个字符串,但最后您尝试打印两个不同的字符串。

名为 new_file_name 的变量实际上指向同一文件名的一部分。

字符串 vce 可能出现在文件名中的任何位置,而不仅仅是扩展名。 如果文件名是 srvce.vce 怎么办?

您可能想找到最后一个 . 字符串中的字符,然后检查其后面是否有预期的扩展名,然后替换该扩展名。 请记住,如果通过修改原始缓冲区来执行此操作,则之后将无法打印旧字符串。

There are a few problems with:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

There is only storage for one string, but at the end you attempt to print two different strings.

The variable named new_file_name actually points to part of the same filename.

The string vce might occur anywhere within a filename, not just an the extension. What if the filename was srvce.vce?

You probably want to find the last . character in the string, then check whether it is followed by the expected extension, and then replace that extension. And remember that if you do this by modifying the original buffer, you will not be able to print the old string afterwards.

救赎№ 2024-07-23 02:48:18

而不是去寻找。 或 vce 其中任何一个都可能在字符串中出现多次,计算字符串的长度并减去 3 以指向扩展名。 使用 strncpy 就地替换扩展名。

size_t length;
char* pextension;
char file_name[80] = "filename.vce";
printf("file name: %s\n", file_name);    
length = strlen(file_name);
pextension = file_name + length - 3;
strncpy(pextension, "wav", 3);
printf("new file name: %s\n", file_name);

Rather than search for . or vce either of which may appear multiple times in the string, calculate the length of the string and subtract 3 to point to the extension. Replace the extension in-place using strncpy.

size_t length;
char* pextension;
char file_name[80] = "filename.vce";
printf("file name: %s\n", file_name);    
length = strlen(file_name);
pextension = file_name + length - 3;
strncpy(pextension, "wav", 3);
printf("new file name: %s\n", file_name);
人生戏 2024-07-23 02:48:18

我会这样做

char file_name[80] = "filename.vce";
char *pExt;

pExt = strrchr(file_name, ".");
if( pExt )
  strcpy(++pExt, "wav");
else
{
 // hey no extension
}
printf("file name: %s\n", file_name);

你需要在每个c 程序中进行指针操作。 当然,您需要对缓冲区溢出等进行更多检查,甚至使用路径特定功能。

I would do this

char file_name[80] = "filename.vce";
char *pExt;

pExt = strrchr(file_name, ".");
if( pExt )
  strcpy(++pExt, "wav");
else
{
 // hey no extension
}
printf("file name: %s\n", file_name);

You NEED to do pointer manipulation in every c program. Of course you'd do some more checking for buffer over runs etc. or even use the path specific functions.

想你只要分分秒秒 2024-07-23 02:48:18

您必须在 new_file_name 末尾手动添加零终止符,因为 strncpy() 不会在您的情况下添加它。

只是碰巧您在正确的位置已经有零字节,但不能保证在所有情况下都如此,因此

new_file_name[3] = '\0';

strncpy() 之后执行类似操作是一个好习惯。

另请注意,字符串“vce”可能会出现在文件名中。

You have to manually add zero-terminator at the end of new_file_name because strncpy() won't add it in your case.

It just happened that you already have zero byte at right place but it cannot be guaranteed in all situations so it is a good habit to do things like

new_file_name[3] = '\0';

after strncpy().

Also beware that string "vce" may appear inside filename.

埋情葬爱 2024-07-23 02:48:18

您的代码存在一些问题。 这是一个不同的做法,其中内联注释了更改:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;

printf("old file name: '%s'\n", file_name);
/* Use strrstr(), to find the last occurance, and include the period. */
new_file_name = strrstr(file_name, ".vce");
if(new_file_name != NULL)
{
  /* Use plain strcpy() to make sure the terminator gets there.
   * Don't forget the period.
  */
  strcpy(new_file_name, ".wav");
}
printf("new file name: '%s'\n", file_name);

这仍然可以改进,例如,它不会检查是否有足够的空间来包含新扩展。 但它确实以比戳单个字符更自然的方式终止字符串。

There are a few issues with your code. Here's a different take, with the changes commented inline:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;

printf("old file name: '%s'\n", file_name);
/* Use strrstr(), to find the last occurance, and include the period. */
new_file_name = strrstr(file_name, ".vce");
if(new_file_name != NULL)
{
  /* Use plain strcpy() to make sure the terminator gets there.
   * Don't forget the period.
  */
  strcpy(new_file_name, ".wav");
}
printf("new file name: '%s'\n", file_name);

This can still be improved, it doesn't check that there is enough room to include the new extension, for instance. But it does terminate the string, in a slighly more natural fashion than poking at single characters.

放肆 2024-07-23 02:48:18

我很无聊,我没有指出原始代码中的问题,而是编写了自己的代码。 为了指导目的,我试图保持清晰。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/* Replace the last suffix in a filename with a new suffix. Copy the new
   name to a new string, allocated with malloc. Return new string. 
   Caller MUST free new string.

   If old name has no suffix, a period and the new suffix is appended
   to it. The new suffix MUST include a period it one is desired.

   Slashes are interepreted to separate directories in the filename.
   Suffixes are only looked after the last slash, if any.

   */
char *replace_filename_suffix(const char *pathname, const char *new_suffix)
{
    size_t new_size;
    size_t pathname_len;
    size_t suffix_len;
    size_t before_suffix;
    char *last_slash;
    char *last_period;
    char *new_name;

    /* Allocate enough memory for the resulting string. We allocate enough
       for the worst case, for simplicity. */
    pathname_len = strlen(pathname);
    suffix_len = strlen(new_suffix);
    new_size = pathname_len + suffix_len + 1;
    new_name = malloc(new_size);
    if (new_name == NULL)
        return NULL;

    /* Compute the number of characters to copy from the old name. */
    last_slash = strrchr(pathname, '/');
    last_period = strrchr(pathname, '.');
    if (last_period && (!last_slash || last_period > last_slash))
        before_suffix = last_period - pathname;
    else
        before_suffix = pathname_len;

    /* Copy over the stuff before the old suffix. Then append a period
       and the new suffix. */
#if USE_SPRINTF
    /* This uses snprintf, which is how I would normally do this. The
       %.*s formatting directive is used to copy a specific amount
       of text from pathname. Note that this has the theoretical
       problem with filenames larger than will fit into an integer. */
    snprintf(new_name, new_size, "%.*s%s", (int) before_suffix, pathname,
             new_suffix);
#else
    /* This uses memcpy and strcpy, to demonstrate how they might be
       used instead. Much C string processing needs to be done with
       these low-level tools. */
    memcpy(new_name, pathname, before_suffix);
    strcpy(new_name + before_suffix, new_suffix);
#endif

    /* All done. */
    return new_name;
}


int main(int argc, char **argv)
{
    int i;
    char *new_name;

    for (i = 1; i + 1 < argc; ++i) {
        new_name = replace_filename_suffix(argv[i], argv[i+1]);
        if (new_name == NULL) {
            perror("replace_filename_suffix");
            return EXIT_FAILURE;
        }
        printf("original: %s\nsuffix: %s\nnew name: %s\n",
               argv[i], argv[i+1], new_name);
        free(new_name);
    }
    return 0;
}

I'm bored, and instead of pointing out problems in the original code, I wrote my own. I tried to keep it clear for instructive purposes.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/* Replace the last suffix in a filename with a new suffix. Copy the new
   name to a new string, allocated with malloc. Return new string. 
   Caller MUST free new string.

   If old name has no suffix, a period and the new suffix is appended
   to it. The new suffix MUST include a period it one is desired.

   Slashes are interepreted to separate directories in the filename.
   Suffixes are only looked after the last slash, if any.

   */
char *replace_filename_suffix(const char *pathname, const char *new_suffix)
{
    size_t new_size;
    size_t pathname_len;
    size_t suffix_len;
    size_t before_suffix;
    char *last_slash;
    char *last_period;
    char *new_name;

    /* Allocate enough memory for the resulting string. We allocate enough
       for the worst case, for simplicity. */
    pathname_len = strlen(pathname);
    suffix_len = strlen(new_suffix);
    new_size = pathname_len + suffix_len + 1;
    new_name = malloc(new_size);
    if (new_name == NULL)
        return NULL;

    /* Compute the number of characters to copy from the old name. */
    last_slash = strrchr(pathname, '/');
    last_period = strrchr(pathname, '.');
    if (last_period && (!last_slash || last_period > last_slash))
        before_suffix = last_period - pathname;
    else
        before_suffix = pathname_len;

    /* Copy over the stuff before the old suffix. Then append a period
       and the new suffix. */
#if USE_SPRINTF
    /* This uses snprintf, which is how I would normally do this. The
       %.*s formatting directive is used to copy a specific amount
       of text from pathname. Note that this has the theoretical
       problem with filenames larger than will fit into an integer. */
    snprintf(new_name, new_size, "%.*s%s", (int) before_suffix, pathname,
             new_suffix);
#else
    /* This uses memcpy and strcpy, to demonstrate how they might be
       used instead. Much C string processing needs to be done with
       these low-level tools. */
    memcpy(new_name, pathname, before_suffix);
    strcpy(new_name + before_suffix, new_suffix);
#endif

    /* All done. */
    return new_name;
}


int main(int argc, char **argv)
{
    int i;
    char *new_name;

    for (i = 1; i + 1 < argc; ++i) {
        new_name = replace_filename_suffix(argv[i], argv[i+1]);
        if (new_name == NULL) {
            perror("replace_filename_suffix");
            return EXIT_FAILURE;
        }
        printf("original: %s\nsuffix: %s\nnew name: %s\n",
               argv[i], argv[i+1], new_name);
        free(new_name);
    }
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文