有没有可能仅打印C字符串的特定部分,而不制作单独的子字符串?

91

假设我有以下内容:

char* string = "Hello, how are you?";

如何只打印该字符串的最后5个字节?如何只打印该字符串的前5个字节?是否有一种类似于printf的变体可以实现这一点?

3个回答

156

如何只打印出这个字符串的最后5个字节?

可以,只需将指针传递给倒数第五个字符。你可以通过 string + strlen(string) - 5 来确定它。

那么前5个字节呢?

使用精度说明符:%.5s

#include <stdio.h>
#include <string.h>
char* string = "Hello, how are you?";

int main() {
  /* print  at most the first five characters (safe to use on short strings) */
  printf("(%.5s)\n", string);

  /* print last five characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - 5);

  int n = 3;
  /* print at most first three characters (safe) */
  printf("(%.*s)\n", n, string);

  /* print last three characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - n);
  return 0;
}

@Tim - 不用谢。别忘了给所有有用的答案点赞,并接受解决你问题的答案。(顺便说一句,注意其他帖子中的建议--如果你的字符串太短,那么这段代码将会失败。) - Robᵩ
根据@Tim在其他答案中的评论更新了示例程序。 - Robᵩ
1
请注意,printf 仍会在第一个空字符处停止。 - Flimm
1
惊人的答案。我知道有很多事情可以做,但这仍然让我感到惊讶。非常感谢。 - Anton Krug

23

是的,可以使用以下内容获取该字符串的最后五个字节:

printf ("%s\n", &(string[strlen (string) - 5]));

前五个可以通过以下方式完成:

printf ("%.5s\n", string);

你可以结合两者来获取字符串中的子字符串。单词how可以通过以下方式打印:

printf ("%.3s\n", &(string[strlen (string) + 7]));

要小心,确保字符串足够长才能使用此方法。如果是一个只有一个字符的字符串并尝试打印其最后五个字符,将会导致未定义的行为,因为索引会变成-4。换句话说,在尝试此操作之前,请检查字符串长度。


2
谢谢,非常有启发性。如果您在编译时不知道n是多少,是否可以打印字符串的前n个字节?比如说n是一个int,我能否只使用printf(“%ns”,string);?另外,在您的“printf(”%5.5s \ n“,string)”中为什么是”5.5“而不是”5“(以及在另一个中为什么是3.3)? - Tim
5
是的。请查看%*s格式说明符。基本上,在字符串之前提供一个整数,指定字符串的宽度。 - Jörgen Sigvardsson
1
@Tim:是的,Jörgen已经说明了如何使用类似int x = 3; printf ("%.*s, x, "abcde")的东西。至于这两个数字,在这种情况下并不是真正必要的,因为你知道你有足够的字符,但我仍然出于习惯而这样做。对于字符串来说,它实际上是最小和最大长度。由于在这里是多余的,所以我会把它拿掉。 - paxdiablo
1
@JörgenSigvardsson:我认为你指的是%.*s格式说明符,而不是%*s格式说明符。 - Flimm
请注意,printf 仍会在第一个空字符处停止。 - Flimm
@Flimm:诚然,我已经在Windows上工作了相当长的时间,所以有可能我使用了一个旧的微软术语。 - Jörgen Sigvardsson

-1

有两种解决方案:

假设给定一个可预测的字符串,长度相同 - 我将以日期为例,并要求将其拆分为 HH:MM:SS.DDDDDDD

char date[14] = "2359591234567";

[1]易读的实现:

char hh[3] = {0};
char mm[3] = {0};
char ss[3] = {0};
char dec[8] = {0};
strncpy ( hh, date, 2 );
strncpy ( mm, date+2, 2 );
strncpy ( ss, date+4, 2 );
strncpy ( dec, date+6, 7 );

printf("%s:%s:%s.%s\n", hh, mm, ss, dec);

[2] 简短实现:

要么:

printf("%.2s:%.2s:%.2s.%.7s\n", date, date+2, date+4, date+6);

或者:

printf("%2.2s:%2.2s:%2.2s.%7.7s\n", date, date+2, date+4, date+6);

应该可以工作。

您可以使用 sprintf 将输出复制到缓冲区中,而不是使用 printf。我还会检查正确的长度以避免不可预知的行为。

在任何情况下 - 输出将是:

23:59:59.1234567

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接