Not printing new lines with printf

  • A+
Category:Languages

I am currently printing a string using printf("'%.*s'/n", length, start);, where start is a const char* and length is an int.

The string being printed sometimes contains newline characters /n which mess up the formatting, is it possible for them to be replaced with the characters / and n in the printed output, instead of the /n character. If not, could you help with a function that would replace the characters?

The string is a malloc'd string that is has other references from different pointers so it cannot be changed.

EDIT: I have written the following code which I think does what I need it to

static void printStr(const char* start, int length) {   char* buffer = malloc(length * sizeof(char));   int processedCount = 0;   for(int i = 0; i < length; i++) {     char c = start[i];     if(c == '/n') {       printf("%.*s//n", processedCount, buffer);       processedCount = 0;     } else {       buffer[processedCount] = c;       processedCount++;     }   }   printf("%.*s", processedCount, buffer);   free(buffer); } 

 


I would implement your custom print function slightly differently:

#include <stdlib.h> #include <ctype.h> #include <stdio.h> #include <errno.h>  static int output_escaped(FILE *out, const char *str, const char *end) {     int  count = 0;     while (str < end)         switch (*str) {         case '//': fputs("////", out); count++; break;         case '/a': fputs("//a", out);  count++; break;         case '/b': fputs("//b", out);  count++; break;         case '/t': fputs("//t", out);  count++; break;         case '/n': fputs("//n", out);  count++; break;         case '/v': fputs("//v", out);  count++; break;         case '/f': fputs("//f", out);  count++; break;         case '/r': fputs("//r", out);  count++; break;         default:             if (isprint((unsigned char)(*str)))                 fputc(*str, out);             else {                 fprintf(out, "//x%02x", (unsigned char)(*str));                 count += 3; /* Note: incremented by one later */             }         }         str++;         count++;     }     return count; } 

with wrapper functions

int escape(const char *str) {     if (!stdout || !str) {         errno = EINVAL;         return -1;     } else         return output_escaped(stdout, str, str + strlen(str)); }  int escapen(const char *str, const size_t len) {     if (!stdout || !str) {         errno = EINVAL;         return -1;     } else         return output_escaped(stdout, str, str + len); }  int fescape(FILE *out, const char *str) {     if (!out || !str) {         errno = EINVAL;         return -1;     } else         return output_escaped(out, str, str + strlen(str)); }  int fescapen(FILE *out, const char *str, const size_t len) {     if (!out || !str) {         errno = EINVAL;         return -1;     } else         return output_escaped(out, str, str + len); } 

The four wrappers cater for the cases when you want to print the entire thing, or just some len first characters, to stdout or a specific stream. All return the number of characters output, or -1 if an error occurs (and errno set).

Note that this prints / as //, and other non-printable characters using a hexadecimal escape sequence /x00 to /xFF. If you want octal (/001 through /377) rather than hexadecimal escapes, use

            else {                 fprintf(out, "//%03o", (unsigned char)(*str));                 count += 3; /* Note: incremented by one later */             } 

instead.

The (unsigned char) casts ensure that the character value is never negative.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: