sprintf() without trailing null space in C

后端 未结 8 1288
鱼传尺愫
鱼传尺愫 2021-02-01 13:37

Is there a way to use the C sprintf() function without it adding a \'\\0\' character at the end of its output? I need to write formatted text in the middle of a fixed width stri

相关标签:
8条回答
  • 2021-02-01 13:57

    There is no way to tell sprintf() not to write a trailing null. What you can do is use sprintf() to write to a temporary string, and then something like strncpy() to copy only the bytes that you want.

    0 讨论(0)
  • 2021-02-01 13:58

    Here's an option for memory constrained devices. It trades off speed for using less RAM. I sometimes have to do this to update the middle of a string that gets printed to a LCD.

    The idea is that you first call snprintf with a zero sized buffer to determine which index will get clobbered by the null terminator.

    You can run the below code here: https://rextester.com/AMOOC49082

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char buf[100] = { 'a', 'b', 'c', 'd', 'e' };
      const size_t buf_size = sizeof(buf);
      const int i = 123;
    
      int result = snprintf(buf, 0, "%i", i);
      if (result < 0)
      {
        printf("snprintf error: %i\n", result);
        return -1;
      }
    
      int clobbered_index = result; //this index will get the null term written into it
    
      if (result >= buf_size)
      {
        printf("buffer not large enough. required %i chars\n", result + 1);
        return -1;
      }
    
      char temp_char = buf[clobbered_index];
      result = snprintf(buf, buf_size, "%i", i); //add result error checking here to catch future mistakes
      buf[clobbered_index] = temp_char;
    
      printf("buf:%s\n", buf);
    
      return 0;
    }
    

    Prints buf:123de

    0 讨论(0)
  • 2021-02-01 14:10

    sprintf returns the length of the string written (not including the null terminal), you could use that to know where the null terminal was, and change the null terminal character to something else (ie a space). That would be more efficient than using strncpy.

     unsigned int len = sprintf(str, ...);
     str[len] = '<your char here>';
    
    0 讨论(0)
  • 2021-02-01 14:11

    Actually this example will not add a null if you use snprintf:

    char name[9] = "QQ40dude";  
    unsigned int i0To100 = 63;  
    _snprintf(&name[2],2,"%d",i0To100);  
    printf(name);// output will be: QQ63dude  
    
    0 讨论(0)
  • 2021-02-01 14:12

    Since you're writing to a fixed area, you can do it like this:

    // pointer to fixed area we want to write to
    char* s;
    
    // number of bytes needed, not including the null
    int r = snprintf(0, 0, <your va_args here>);
    
    // char following the last char we will write - null goes here
    char c = s[r + 1];
    
    // do the formatted write
    snprintf(s, r + 1, <your_va_args here>);
    
    // replace what was overwritten
    s[r + 1] = c;
    
    0 讨论(0)
  • 2021-02-01 14:17

    You could also use your fixed width string as a format string like this:

    char my_fixed_width_string_format[] = "need 10 chars starting here: %10s";
    char my_fixed_width_string[40];
    char string_to_print[] = "abcdefghijklmnop";
    sprintf(my_fixed_width_string, my_fixed_width_string_format, string_to_print;
    printf(my_fixed_width_string);
    

    should yield

    need 10 chars starting here: abcdefghij

    0 讨论(0)
提交回复
热议问题