我是C语言的初学者,所以我想看一段代码,该代码包含对给定文件中的字符,单词和行数进行计数。我在下面的代码中发现了问题,但我不明白为什么我们必须在while循环后增加最后一个单词的单词和行数:if (characters > 0)...
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
char path[100];
char ch;
int characters, words, lines;
/* Input path of files to merge to third file */
printf("Enter source file path: ");
scanf("%s", path);
/* Open source files in 'r' mode */
file = fopen(path, "r");
/* Check if file opened successfully */
if (file == NULL) {
printf("\nUnable to open file.\n");
printf("Please check if file exists and you have read privilege.\n");
exit(EXIT_FAILURE);
}
/*
* Logic to count characters, words and lines.
*/
characters = words = lines = 0;
while ((ch = fgetc(file)) != EOF) {
characters++;
/* Check new line */
if (ch == '\n' || ch == '\0')
lines++;
/* Check words */
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0')
words++;
}
/* Increment words and lines for last word */
if (characters > 0) {
words++;
lines++;
}
/* Print file statistics */
printf("\n");
printf("Total characters = %d\n", characters);
printf("Total words = %d\n", words);
printf("Total lines = %d\n", lines);
/* Close files to release resources */
fclose(file);
return 0;
}
答案 0 :(得分:0)
该程序存在一些问题:
ch
必须定义为int
,才能正确检测到EOF
。
scanf("%s", path);
的超长输入将溢出path
并导致未定义的行为。还要检查返回值以检测无效的输入或文件的提前结束
if (scanf("%99s", path) != 1)
return 1;
测试ch == '\0'
以计算行数是有争议的。标准的wc
Unix实用程序不会将空字节用作行分隔符。
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0')
也不是检测单词边界的标准方法。 if (isspace(ch))
更惯用。
单词计数错误:多个空格将计为多个单词!相反,您应该检测边界,即空格字符后跟非空格字符。
最后一个测试是解决上述问题的a脚尝试,但这还不够。如果流不以换行符结尾,则确实需要进行额外的测试以计算流的最后一个。
这是更正的版本:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
char path[1024];
int ch, last;
long long int characters, words, lines;
/* Input path of files to merge to third file */
printf("Enter source file path: ");
if (scanf("%255s", path) != 1) {
printf("Invalid input\n");
return EXIT_FAILURE;
}
/* Open source files in 'r' mode */
file = fopen(path, "r");
/* Check if file opened successfully */
if (file == NULL) {
printf("Unable to open file %s\n", path);
printf("Please check if file exists and you have read privilege.\n");
return EXIT_FAILURE;
}
/*
* Logic to count characters, words and lines.
*/
characters = words = lines = 0;
last = '\n';
while ((ch = fgetc(file)) != EOF) {
characters++;
/* Check new line */
if (ch == '\n')
lines++;
/* Check words */
if (!isspace(ch) && isspace(last))
words++;
last = ch;
}
/* Increment words and lines for last word */
if (last != '\n') {
lines++;
}
/* Print file statistics */
printf("\n");
printf("Total characters = %lld\n", characters);
printf("Total words = %lld\n", words);
printf("Total lines = %lld\n", lines);
/* Close file to release resources */
fclose(file);
return 0;
}
答案 1 :(得分:0)
将需要根据输入的输入文件是否以漂亮的换行符('\ n')结尾来调整输出。
对于在所有行(包括最后一行)都以'\ n'结尾的普通sain文本文件,请在循环后删除这些增量。
但是对于这些特殊情况,似乎需要对程序进行一些调试,这取决于您的定义。但我强烈建议使用Linux / Unix命令wc
作为参考和决胜局。