这是我的代码,输出的每个字母都打印两次。它不是文本文件,只有在我插入putchar(tolower)
语句时才会发生,但它的格式完全正确。该陈述有什么问题?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_STRING_SIZE 20
#define MAX_LIST_SIZE 50
int readFile(char *filename); /* function declaration for readFile, defined below */
void punct();
/* main function */
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("%s: usage %s textFileName \n", argv[0], argv[0]);
exit(1);
}
readFile(argv[1]);
return 0;
}
int readFile(char *filename) {
char ch;
FILE *fPtr;
fPtr = fopen(filename, "r"); /*open file filename, r is read only */
if (!fPtr) {
return 0;
}
while ((ch = fgetc(fPtr)) != EOF) {
putchar(tolower(ch));
printf("%c", ch);
}
fclose(fPtr);
return 1; /* because success */
}
答案 0 :(得分:5)
输出的每个字母都打印两次
这两行:
putchar(tolower(ch));
printf("%c", ch);
打印两次相同的角色。
putchar
将一个字符添加到标准输出中
printf
将格式化文本放入标准输出。在您的情况下,格式化的文本是在上面的行上打印的相同字符。
只有当我在
中插入putchar(tolower)语句时才会发生这种情况
这是因为这样做实际上使输出加倍。
答案 1 :(得分:0)
您的代码中存在多个问题:
ch
类型定义 int
,以适应fgetc()
的所有可能返回值。这些都是unsigned char
类型的值加上特殊值EOF
。存储到char
变量会带来多个问题:
无法再准确测试值EOF
。如果类型char
未签名,则(ch = fgetc(fp)) == EOF
始终为false。相反,如果类型char
已签名,则(ch = fgetc(fp)) == EOF
可能属于ch = '\377
,这是一个有效的字节值。
如果char
已签名,则tolower(ch)
对于否定值有未定义的行为。
从文件读取的每个字节输出两次:首先是putchar(tolower(ch));
,第二次是printf("%c", ch);
。
以下是更正后的版本:
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
char *progname;
int readFile(const char *filename) {
int ch;
FILE *fPtr;
fPtr = fopen(filename, "r"); /* open file filename for reading */
if (!fPtr) {
fprintf(stderr, "%s: cannot open %s: %s\n",
progname, filename, strerror(errno));
return 1; /* failure */
}
while ((ch = fgetc(fPtr)) != EOF) {
putchar(tolower(ch));
}
fclose(fPtr);
return 0; /* success */
}
int main(int argc, char *argv[]) {
progname = argv[0];
if (argc < 2) {
fprintf(stderr, "usage: %s textFileName\n", progname);
return 1;
}
return readFile(argv[1]);
}