我正在编写一个程序,它接受一个输入文件,其中包含由主题标签(A,B,C ...)组成的字符图,从控制台读取字符串并通过绘制字符来打印出该字符串到输入文件。
注意:正如您将在下面看到的那样,输入文件包含“。”而不是空格。这些在我的代码中被替换为空格。
由于某些原因,当我在绘制一个角色后打印一个换行符时,该角色的部分会消失。
我知道这听起来很复杂,所以我将提供下面的所有文件和输出。
以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct{
char znak[5][5 + 1];
} slovo;
void napuni(slovo *znakovi, FILE *ulaz);
int main(){
int i,j;
FILE *ulaz = fopen("ascii.in", "r");
slovo *znakovi = calloc(27, sizeof(slovo));
napuni(znakovi, ulaz);
fclose(ulaz);
FILE *izlaz = fopen("ascii.out", "w");
char *tekst = calloc(50,sizeof(char));
fgets(tekst,50,stdin);
char *znak = strchr(tekst, '#');
*znak = '\0';
int duljina = strlen(tekst);
for (j = 0; j < 5; j++){
for (i = 0; i < duljina; i++){
int znak2 = toupper(tekst[i]) - 65;
fprintf(izlaz, "%s", znakovi[znak2].znak[j]);
}
fprintf(izlaz,"\n");
}
fclose(izlaz);
return 0;
}
void napuni(slovo *znakovi, FILE *ulaz){
char redak[6];
int i,j;
for (i = 0; i < 27; i++){
for (j = 0; j < 7; j++){
if (feof(ulaz)) break;
fgets(redak,6,ulaz);
if (redak[0] == '\n' || redak[0] == 32) continue;
char *znak = strchr(redak, '.');
while(znak != NULL){
*znak = 32;
znak = strchr(redak,'.');
}
strcpy(znakovi[i].znak[j], redak);
printf("\n%s",znakovi[i].znak[j]); // this line prints the character to console for testing
}
printf("\n"); //when this line is uncommented pieces of the character disappear
}
}
这是输入文件:
..#..
.#.#.
.###.
.#.#.
.#.#.
.##..
.#.#.
.##..
.#.#.
.##..
..#..
.#.#.
.#...
.#.#.
..#..
.##..
.#.#.
.#.#.
.#.#.
.##..
.###.
.#...
.##..
.#...
.###.
.###.
.#...
.##..
.#...
.#...
..#..
.#...
.#.##
.#..#
..##.
.#.#.
.#.#.
.###.
.#.#.
.#.#.
..#..
..#..
..#..
..#..
..#..
...#.
...#.
...#.
.#.#.
..#..
.#.#.
.#.#.
.##..
.#.#.
.#.#.
.#...
.#...
.#...
.#...
.###.
#...#
##.##
#.#.#
#...#
#...#
#..#.
##.#.
#.##.
#..#.
#..#.
..#..
.#.#.
.#.#.
.#.#.
..#..
.##..
.#.#.
.##..
.#...
.#...
..#..
.#.#.
.#.#.
.#.#.
..##.
.##..
.#.#.
.##..
.##..
.#.#.
..##.
.#...
.###.
...#.
.##..
.###.
..#..
..#..
..#..
..#..
.#.#.
.#.#.
.#.#.
.#.#.
.###.
.#.#.
.#.#.
.#.#.
.#.#.
..#..
#...#
#...#
#.#.#
#.#.#
.#.#.
#...#
.#.#.
..#..
.#.#.
#...#
.#.#.
.#.#.
.###.
...#.
..##.
.###.
...#.
..#..
.#...
.###.
..#..
.#.#.
...#.
..#..
..#..
当我不在其间插入换行符时,这是一个测试输出(只是一次打印出一个字符):
#
# #
###
# #
# #
##
# #
##
# #
##
#
# #
#
# #
#
##
# #
# #
# #
##
###
#
##
#
###
###
#
##
#
#
#
#
# ##
# #
##
# #
# #
###
# #
# #
#
#
#
#
#
#
#
#
# #
#
# #
# #
##
# #
# #
#
#
#
#
###
# #
## ##
# # #
# #
# #
# #
## #
# ##
# #
# #
#
# #
# #
# #
#
##
# #
##
#
#
#
# #
# #
# #
##
##
正如您所见,它的行为符合预期。但是,如果我在其间插入换行符,则字符会被破坏。见下文:
#
# #
###
# #
# #
##
# #
##
# #
##
#
# #
#
# #
#
##
# #
# #
# #
##
###
#
##
#
###
###
#
##
#
#
#
#
# ##
# #
##
# #
# #
###
# #
# #
#
#
#
#
#
#
#
#
# #
#
# #
# #
##
# #
# #
#
#
#
#
###
# #
## ##
# # #
# #
# #
# #
## #
# ##
# #
# #
#
# #
# #
# #
#
##
# #
##
#
#
#
# #
# #
# #
##
##
基本上就是这样。我是C的初学者,所以感谢任何帮助。
答案 0 :(得分:1)
您的代码中存在缓冲区溢出错误。您将redak
声明为:
char redak[6];
然后用这一行覆盖内存的结尾:
redak[6] = '\0';
结果是未定义的行为。请注意,像valgrind
这样的工具可以帮助您轻松捕获此类错误。
另一个问题是您的for
循环:条件应该是j<6
而不是7。
最后,redak
的大小应为7,fgets()
也会相应更改。否则fgets
不会读取换行符,因此您开始阅读&#34; next&#34;从错误的位置排队。请记住,fgets
最多只读取一个大小字符。
这也意味着char znak[5][5 + 1]
应更改为char znak[6][7]
。