【问题标题】:Is it possible to print out only a certain section of a C-string, without making a separate substring?是否可以只打印 C 字符串的某个部分,而不制作单独的子字符串?
【发布时间】:2011-12-08 12:15:34
【问题描述】:

假设我有以下内容:

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

是否可以只打印该字符串的最后 5 个字节?仅前 5 个字节呢? printf 是否有一些变体可以实现这一点?

【问题讨论】:

    标签: c printf c-strings


    【解决方案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);
    

    应该可以。

    代替 printf - 您可以使用 sprintf 并复制到缓冲区。我还会检查正确的长度以避免不可预知的行为。

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

    23:59:59.1234567
    

    【讨论】:

      【解决方案2】:

      是否可以只打印该字符串的最后 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 - 欢迎您。不要忘记为所有有用的答案投票,并接受解决您问题的答案。 (附注:请注意另一篇文章中的建议——如果您的字符串太短,则此代码将失败。)
      • 更新了示例程序以在其他答案中解决 @Tim 的 cmets。
      • 请注意,printf 仍会在第一个空字符处停止。
      • 惊人的答案。我知道可以做很多事情,但这仍然让我感到惊讶。非常感谢。
      【解决方案3】:

      是的,该字符串的最后五个字节可以用:

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

      前五个可以用:

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

      您也可以将两者结合起来以获取字符串中的子字符串。 how这个词可以打印成:

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

      你做必须小心字符串足够长才能正常工作。打印单字符字符串的最后五个字符将导致未定义的行为,因为索引以-4 结束。换句话说,在尝试之前检查字符串长度。

      【讨论】:

      • 谢谢,非常有用。如果您在编译时不知道 n 是什么,是否可以打印出字符串的前 n 个字节?假设 n 是一个 int,我可以只使用 printf("%ns", string); ?另外,为什么在“printf ("%5.5s\n", string);" 中它是 "5.5" 而不是 "5" (同样,另一个是 3.3)?
      • 蒂姆:是的。查看 %*s 格式说明符。基本上,您在字符串之前提供一个 int,它指定字符串的宽度。
      • @Tim:是的,Jörgen 已经说明了如何使用 int x = 3; printf ("%.*s, x, "abcde") 之类的东西。至于 two 数字,在这种情况下这并不是真正必要的,因为您知道您有足够的字符,但我仍然出于习惯的力量这样做。对于字符串,它实际上是最小和最大长度。我把它拿出来,因为它在这里是多余的。
      • @JörgenSigvardsson:我认为您的意思是 %.*s 格式说明符,而不是 %*s 格式说明符。
      • 请注意,printf 仍会在第一个空字符处停止。
      猜你喜欢
      • 2019-08-05
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 2019-06-17
      • 2019-06-11
      • 1970-01-01
      相关资源
      最近更新 更多