【问题标题】:setting variable to contain part of string in c programming [closed]在c编程中设置变量以包含字符串的一部分[关闭]
【发布时间】:2021-04-21 23:36:12
【问题描述】:

我有一个变量 str,它是“Hello Me”。

我想写一个程序,只显示字符串的前 5 个字符,即 Hello。

下面是我尝试执行此操作的代码的 sn-p。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <malloc.h>
#include <string.h>

int main(int argC, char **argV)
{
        char str[100]="Hello Me";
        char c[100];
        sprintf(c,"%s\n",str[1,4]);
        printf("string is %s\n",str);
}

不幸的是,在尝试执行此操作时,我遇到了分段错误错误。如何调整程序以获得所需的结果。我需要将 c 之类的字符显示为数组。

【问题讨论】:

  • str[1,4]str[4] 一样,都是单个字符,不是字符串。这就是段错误的原因。要修复它,请尝试sprintf(c, "%.5s\n", str);。当然,您必须在 printf 中打印 c 才能看到结果。
  • 现在,如果我想以第二个字符开始字符串,例如 c 等于 ello,我该怎么办?
  • 提示:char* str = "..."。除非您需要 mutable 缓冲区,否则不要打扰 [100]。你可以让它像char str[] = "..."一样自动调整大小。
  • 这能回答你的问题吗? Strings in C, how to get subString

标签: c string variables


【解决方案1】:

你可以构建一个切片函数,它有四个输入,dst string,src string,slice start pos,slice end pos。

注意索引应该在 src 字符串长度范围内。

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

char *
slice_str (char *buffer, char *str, int start, int end)
{
  int j = 0;
  for (int i = start; i <= end; ++i)
    {
      buffer[j++] = str[i];
    }
  buffer[j] = 0;
  return buffer;
}

int
main (void)
{
  char *str = "abcdef";
  int len = strlen (str);
  char ostr[len + 1];
  int start;
  int end;
//index
  start = 1;
  end = 2;
  slice_str (ostr, str, start, end);
//show
  printf ("%s\n--------------\n|index %d to %d|\n--------------\n%s\n", str,
          start, end, ostr);
  return 0;
}

【讨论】:

    【解决方案2】:

    从一个字符串中只打印五个字符:

    printf("The first five characters are %.5s\n", the_string);
    

    无需复制字符串即可。 (注意%.5s 格式的区别,即“如果字符串参数长于五个字符,则仅使用前五个字符。”和%5s,即“如果字符串短于五个字符,则首先输出足够的空格以使总宽度为 5。”这两个选项是相互独立的,因此您可以同时使用:%7.5s 将是“最多使用五个字符,并将它们放在七个字符的字段。如果要在右侧而不是左侧填充,请使用减号。)

    事实上,复制字符串的需要比您想象的要少得多。不必要的复制既费时又容易出错。它也很常见。所以你应该经常问自己是否真的需要副本。

    如果您确定确实需要复制,您的第一个调用点是strndup,它会为指定大小的子字符串动态分配足够的存储空间:

    char* strndup(const char* original, size_t n);
    

    这可以让你做以下事情:

    char* first_five = strndup(the_string, 5);
    

    (例如,如果the_string 只有三个字符,这不是问题。你会得到所有三个字符。)

    或者,如果你想要一个来自字符串中间的子字符串:

    char* substring = strndup(the_string + start, length);
    

    这不太安全,因为strndup 无法验证the_string 至少有start 字符。为了使其更安全,您可以这样做:

    char* substring = strndup(the_string + strnlen(the_string, start), length);
    

    如果您真的知道start 在范围内,则不必这样做。计算第一个 start 字符,这是 strnlen 所做的,效率不高。但这比计算所有个字符要好,strlen 就是这样做的。

    (如果你觉得the_string + start看起来很奇怪,记住它一模一样&amp;the_string[start]一样;也就是说,它是数组start中元素start的地址the_string .)

    如果可能,您应该始终使用strndup,因为它是唯一(相当)安全的中等标准功能。它(相当)安全,因为它不取决于您是否知道目标字符串足够大。不幸的是,它(和strnlen)还不是 C 标准的一部分(尽管我相信它们很快就会出现),它们只是在 2008 年的修订版中添加到 Posix 中。但它们在 Linux 上已经存在很长时间了,现在在 Mac OS X 上已经存在好几年了。

    不过,您需要使用正确的功能测试宏:

    #define _POSIX_C_SOURCE 200809L
    

     #define _XOPEN_SOURCE 700
    

    这必须在使用该函数的文件中的任何#include 之前。如果您使用 clang 或 gcc,您可以在编译命令中添加 -D 选项。

    如果您需要与 Windows 兼容,则必须找到开源实现;幸运的是,这并不难:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-13
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      相关资源
      最近更新 更多