我目前正在使用printf("'%.*s'\n", length, start);
打印字符串,其中start
为const char*
,长度为int
。
正在打印的字符串有时会包含换行格式\n
,这会影响格式,是否可以将它们替换为打印输出中的字符\
和n
,而不是\n
个字符。
如果没有,你能帮助一个替代角色的功能吗?
该字符串是malloc'd字符串,其中包含来自不同指针的其他引用,因此无法更改。
编辑:我已经编写了以下代码,我认为我需要它来执行
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);
}
答案 0 :(得分:4)
无需分配内存来处理字符串。简单地说,迭代原始的并根据需要打印字符。例如:
#include <stdio.h>
void print(const char * str, int length)
{
for (int i = 0; i < length; ++i) {
if (str[i] == '\n') {
putchar('\\');
putchar('n');
} else
putchar(str[i]);
}
}
int main()
{
print("hello\nworld!", 12);
return 0;
}
答案 1 :(得分:3)
我会以稍微不同的方式实现您的自定义打印功能:
import { of } from "rxjs";
import { delay } from "rxjs/operators";
fakeObservable = of('dummy').pipe(delay(5000));
包装函数
#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;
}
当您想要将整个事物或仅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);
}
首字符打印到len
或特定流时,四个包装器可以满足这些情况。全部返回输出的字符数,如果发生错误则返回-1(并设置errno)。
请注意,这会将stdout
打印为\
,并使用十六进制转义序列\\
打印到\x00
的其他不可打印字符。如果你想要八进制(\xFF
到\001
)而不是十六进制转义,请使用
\377
代替。
else {
fprintf(out, "\\%03o", (unsigned char)(*str));
count += 3; /* Note: incremented by one later */
}
强制转换可确保字符值永远不会为负值。
答案 2 :(得分:1)
这基本上是相同的,但它在内存中使用strchr
来确切地看到我们可以在转义序列之前写入多少char
,并fwrite
将它们全部合并在一起。这可能比一次一个字符输出更快(可能与https://stackoverflow.com/a/37991361/2472827相关。)(未经过彻底测试。)
#include <stdlib.h> /* EXIT_ */
#include <stdio.h> /* perror fwrite fputs */
#include <string.h> /* strchr */
#include <assert.h>
/** Prints the string, escaping newlines to "\n"; a newline will be added at
the end.
@return A non-negative number, otherwise EOF; in the latter case, it shall
set an error indicator for the stream and (may) set {errno} (IEEE Std
1003.1-2001-conforming systems?) */
static int printStr(const char* start) {
const char *so_far = start, *nl;
size_t nchars;
assert(start);
while((nl = strchr(so_far, '\n'))) {
nchars = nl - so_far;
if(fwrite(so_far, 1, nchars, stdout) != nchars
|| fwrite("\\n", 1, 2, stdout) != 2) return EOF;
so_far = nl + 1;
}
/* The rest. */
return fputs(so_far, stdout) == EOF || fputc('\n', stdout) == EOF ? EOF : 1;
}
int main(void) {
return printStr("Lalala\n\nlalala\n\n") == EOF
? perror("string"), EXIT_FAILURE : EXIT_SUCCESS;
}
它不需要length
,但你可以通过检查nchars
,(如果你的字符串不是null
- 终止?)
答案 3 :(得分:1)
您在问题中发布的代码似乎有效,但内存分配失败时潜在的未定义行为除外。它可以简化:不需要临时buffer
,您可以直接从提供的数组打印,避免分配:
static void printStr(const char *s, int length) {
int i, j;
for (i = j = 0; i < length; i++) {
if (s[i] == '\n') {
printf("%.*s\\n", i - j, s + j);
}
}
if (i > j) {
printf("%.*s", i - j, s + j);
}
}