我需要检查我的程序是否正确地在我的字符串中输入这些字符,那么如何才能看到“原始”字符串,这些字符未解析但实际显示?
答案 0 :(得分:5)
如果您读取输入(来自文件或来自用户),则特殊转义码不解析。只有在源代码中的字符串和字符文字中,编译器才会特别处理它们。
编辑:带有输入和输出的简单示例程序,以显示我正在谈论的内容。
#include <stdio.h>
#include <string.h>
int main(int ac, char *av[])
{
char input[32];
printf("Enter input: ");
fgets(input, sizeof(input), stdin);
/* Remove trailing newline */
if (input[strlen(input) - 1] == '\n')
input[strlen(input) - 1] = '\0';
printf("input is \"%s\"\n", input);
return 0;
}
上述程序的示例运行:
Enter input: foo\nbar\thello input is "foo\nbar\thello"
函数fgets
将实际换行留在字符串的末尾。但是,输入中的序列\n
和\t
会将不转换为换行符或制表符(分别)。那是因为它不是处理这些特殊字符序列的输入或输出函数,而是编译器。
如果您在源代码中的字符串或字符文字中包含这些序列,则编译器会识别这些序列并将其更改为正确的换行符,制表符或您编写的任何内容。但是,由于编译器对从文件或用户读取的输入一无所知,因此这些序列不已翻译。
编辑2:如果您想知道如何在字符串中显示 literal 特殊字符,请参阅此程序:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void print_raw_string(const char *str)
{
while (*str != '\0')
{
if (isprint(*str))
fputc(*str, stdout);
else
{
switch (*str)
{
/* First check for known special sequences */
case '\0':
printf("\\0");
break;
case '\a':
printf("\\a");
break;
case '\b':
printf("\\b");
break;
case '\t':
printf("\\t");
break;
case '\n':
printf("\\n");
break;
case '\v':
printf("\\v");
break;
case '\f':
printf("\\f");
break;
case '\r':
printf("\\r");
break;
default:
/* None of the above, print it out as a hex escape sequence */
printf("\\x%02x", *str);
break;
}
}
str++;
}
}
int main(int ac, char *av[])
{
char input[32];
printf("Enter input: ");
fgets(input, sizeof(input), stdin);
printf("Input is: ");
print_raw_string(input);
printf("\n");
return 0;
}
运行程序时:
Enter input: foo bar Input is: foo\tbar\n
答案 1 :(得分:2)
一种可能的解决方案是打印出字符串中的ASCII值,无论它是固定字符串还是来自stdin
,都可以正常工作:
char str[] = "A\tBC1\n";
int j;
for(j = 0; j<strlen(str); str++)
printf("%#x ", str[j]);
输出:
>>0x41 0x9 0x42 0x43 0x31 0xA
来自stdin:
fgets(str, 5, stdin);
for(j = 0; j<strlen(str); j++)
printf("%#x ", str[j]);
输入/输出:
>> 1 2 <---- That's a tab between 1 and 2
>> 0x31 0x9 0x32 0xA
您可以获得幻想并转义字符以显示\t
(0x9)和\n
(0xA)而不是原始值,但如果您只是想验证您是否获得了它们,这应该工作(并且更快)
答案 2 :(得分:1)
您可以转义字符,也可以编写自己的特殊例程:
void print_raw(const char *ch)
{
char *d = ch;
while(*d){
switch(*d){
case '\n':
printf("\\n");
break;
case '\v':
printf("\\n");
break;
case '\r':
printf("\\r");
break;
case '\a':
printf("\\a");
break;
case '\?':
printf("\\?");
break;
case '\"':
printf("\"");
break;
case '\t':
printf("\\t");
break;
case '\b':
printf("\\b");
break;
case '\f':
printf("\\f");
break;
case '\\':
printf("\\");
break;
case '\'':
printf("\'");
break;
default:
putchar(d);
}
}
答案 3 :(得分:0)
只需将字符串打印为一系列字符,例如:
str是你的字符串:
char *ptr = str;
while(*ptr != 0)
{
print("%02X", *ptr);
ptr++;
}
答案 4 :(得分:0)
Printf对\ n等没有任何特殊处理。这些字符序列由编译器解释。试试这个:
$ cat foo.c
#include <stdio.h>
#include <string.h>
int
main(int argc, char **argv)
{
if (argc != 2)
return 1;
printf("%d\n", (int)strlen(argv[1]));
printf("%d\n", (int)strlen("\n"));
printf("[%s]\n", argv[1]);
return 0;
}
$ cc -Wall -O2 -o foo foo.c && ./foo '\n'
2
1
[\n]
$
请注意,我在调用foo时转义\ n,因为如果没有转义,shell会解释\(以不同方式)。