使用 fputs 或其他打印 char 数组 - C

问题描述 投票:0回答:3

第一个数组打印正确。

test[] =

但是,当数组像第二个示例中那样时,
test[][] ={"...","..."};

我收到不兼容的警告。
在使用 fputs 的第二个示例中,它打印时没有换行符,而使用 printf 则不打印任何内容。

#include <stdio.h>
//String to display Test
const char test[] =
"|T|\n\
|E|\n\
|S|\n\
|T|\n\
";

int main(){
   //Print test
   fputs(test,stdout);
   printf("\n");
   return 0;
}

第二个例子。

#include <stdio.h>
#define LINE 4
#define COLN 5
//String to display Test
const char test[LINE][COLN] ={
" |T| ",
" |E| ",
" |S| ",
" |T| "
};

int main(){
    // Print test
    //printf("%s", test);
    fputs(test,stdout);
    printf("\n");
    return 0;
}

警告

_______________________________________________________________________________
field width should have type 'int', but argument has type 'const char (*)[11]'
[-Wformat]           printf("%*s",test);
                              ~^   ~~~
_______________________________________________________________________________
incompatible pointer types passing 'const char[11][11]' 
to parameter of type 'const char ' [-Wincompatible-pointer-types]
fputs(test,stdout);
      ^~~~
passing argument to parameter '__s' here
int fputs(const char __s, FILE* __fp);
                      ^
c printf fputs
3个回答
2
投票

在行中

const char test[LINE][COLN] ={
" |T| ",
" |E| ",
" |S| ",
" |T| "
};

您正在定义一个由 4 个

char
数组组成的数组,这些数组不是以 null 结尾的(因为您定义数组的方式使得没有空间容纳 null 终止字符)。

因此,要打印这 4 个

char
数组中的任何一个,不能使用
fputs
。但是,您可以将
%s
转换格式说明符与
printf
一起使用,但必须限制写入的字符数,例如使用以下语法:

printf( "%.*s\n", COLN, test[0] );

有关更多信息,请参阅

printf
的文档。

如果您还希望能够在各个

fputs
数组上使用
char
,那么您必须以有空间容纳终止空字符的方式定义
char
数组,例如像这样:

const char test[LINE][COLN+1] = {
    " |T| ",
    " |E| ",
    " |S| ",
    " |T| "
};

但是,为了打印所有 4 个

char
数组,您不能简单地使用以下行

fputs(test,stdout);

正如您在代码中所做的那样,因为您一次只能打印一个字符串。因此,你必须写

fputs( test[0], stdout );
printf( "\n" );
fputs( test[1], stdout );
printf( "\n" );
fputs( test[2], stdout );
printf( "\n" );
fputs( test[3], stdout );
printf( "\n" );

为了打印所有 4 个字符串,或者更好,使用循环:

for ( int i = 0; i < LINE; i++ )
{
    fputs( test[i], stdout );
    printf( "\n" );
}

关于你的第一个例子,值得注意的是

const char test[] =
"|T|\n\
|E|\n\
|S|\n\
|T|\n\
";

不是好的编码风格,因为最好缩进除第一行之外的所有行。您可能没有这样做,因为这会导致缩进成为字符串的一部分。不过,这个问题可以通过编写以下代码来解决:

const char test[] =
    "|T|\n"
    "|E|\n"
    "|S|\n"
    "|T|\n";

预处理器将在翻译过程的第 6 阶段将所有 4 个字符串文字连接成一个字符串文字。


0
投票
以下代码有效。

    将 COLN 增加到 6,因为字符串结尾由
  1. '\0'
     声明。
  2. 使用 [i] (i=0 ... 3) 访问测试中的各个字符串
  3. #define LINE 4 #define COLN 6 #include <stdio.h> //String to display Test const char test[LINE][COLN] ={ " |T| ", " |E| ", " |S| ", " |T| " }; int main(){ // Print test printf("%s\n", test[0]); printf("%s\n", test[1]); printf("%s\n", test[2]); printf("%s\n", test[3]); printf("\n"); return 0; }
    ./a.out
     |T| 
     |E| 
     |S| 
     |T| 
    
    
    

0
投票
您正在尝试字符串和字符串数组。

像第一个示例中那样“转义”换行符不是一个好习惯。编译器将从源代码中“连接”字符串,如下面第一个示例所示。

正如其他人所写,第二个示例需要一个循环来逐步遍历每个分隔的字符串。

这里有一些东西要研究...

#include <stdio.h> // These 'fragments' will be 'connected' at compilation time const char test1[] = "|T|\n" "|E|\n" "|S|\n" "|T|\n"; // Equivalent const char test2[] = "|T|\n|E|\n|S|\n|T|\n"; const char *test3[] = { "|T|", "|E|", "|S|", "|T|" }; int main( void ) { puts( "test 1:" ); // puts() appends its own '\n' puts( test1 ); puts( "test 2:" ); puts( test2 ); puts( "test 3:" ); for( int i = 0; i < 4; i++ ) puts( test3[i] ); return 0; }

输出:
test 1:
|T|
|E|
|S|
|T|

test 2:
|T|
|E|
|S|
|T|

test 3:
|T|
|E|
|S|
|T|

下面的评论中提供了 OP 的其他信息,以下内容用于教育目的。

#include <stdio.h> #define COLN 11 // String to display Rocket const char rocket[] = " ^ " " /^\\ " " |-| " " | | " " |W| " " |E| " " |E| " " |E| " " /| |\\ " " / | | \\ " " | | | | "; int main( void ) { for( int i = 0; rocket[i]; i += COLN ) puts( rocket + i ); return 0; }


© www.soinside.com 2019 - 2024. All rights reserved.