C语言文件统计代码求纠错:实现行/词统计及最长行分析
Hey there! Let's walk through your code step by step to fix the bugs and improve its robustness. Here are the key issues I spotted, plus a revised version of your code and some extra tips:
Key Bugs in Your Code
- Filename variable type mismatch: You declared
char filename;which is a single character, but filenames are strings. This will causefopento fail immediately because you're passing an invalid pointer. - Invalid array assignment:
c=fgetc(fp);is wrong—cis a char array, not a single char. Plus, this line skips the first character of your file, which breaks subsequentfgetsreads. - Incorrect array initialization:
lineaMax={0};isn't valid syntax for initializing an array after declaration. You need to usememsetor initialize it when declaring the variable. - Wrong line count logic:
righe++;is outside thewhile(fgets(...))loop, so it will only count 1 line no matter how many lines your file has. - Broken word count logic: Your current code counts every non-space/non-newline character as a word (e.g., "hello" would be counted as 5 words). You need to detect word boundaries (transitions from whitespace to non-whitespace) to count actual words.
- Invalid function call:
print(...)should beprintf(...)—that's a typo that will cause a compiler error. - Uninitialized variable:
paroleRigaisn't initialized, so it will hold a garbage value when you try to use it. - Incorrect longest line word count:
getc(lineaMax)is for reading from file streams, not arrays. You need to iterate over thelineaMaxarray directly. Also, counting spaces and adding 1 doesn't account for leading/trailing spaces or consecutive spaces. - No exit on file open failure: If
fopenreturnsNULL, you print an error but keep executing the rest of the code, which will lead to undefined behavior (accessing a null pointer).
Revised Code
#include <stdio.h> #include <string.h> #include <ctype.h> // Define a constant for line buffer size to avoid magic numbers #define MAX_LINE_LEN 102 int main() { int total_words = 0, total_lines = 0, longest_line_words = 0; char current_line[MAX_LINE_LEN]; char longest_line[MAX_LINE_LEN] = {0}; // Initialize to all zeros char filename[256]; // Use a string for filename FILE *fp; // Ask user for filename (or hardcode if you prefer) printf("Enter filename: "); fgets(filename, sizeof(filename), stdin); // Remove newline from filename if present filename[strcspn(filename, "\n")] = '\0'; fp = fopen(filename, "r"); if (fp == NULL) { printf("Error opening file!\n"); return 1; // Exit immediately on failure } while (fgets(current_line, MAX_LINE_LEN, fp) != NULL) { total_lines++; // Update longest line if current line is longer if (strlen(current_line) > strlen(longest_line)) { strncpy(longest_line, current_line, sizeof(longest_line) - 1); longest_line[sizeof(longest_line) - 1] = '\0'; // Ensure null termination } // Count words in current line int in_word = 0; for (int i = 0; current_line[i] != '\0'; i++) { if (isspace(current_line[i])) { in_word = 0; } else if (!in_word) { in_word = 1; total_words++; } } } // Count words in the longest line int in_word = 0; for (int i = 0; longest_line[i] != '\0'; i++) { if (isspace(longest_line[i])) { in_word = 0; } else if (!in_word) { in_word = 1; longest_line_words++; } } fclose(fp); // Print results printf("Total lines: %d\n", total_lines); printf("Total words: %d\n", total_words); printf("Words in longest line: %d\n", longest_line_words); if (total_lines > 0) { printf("Average words per line: %.2f\n", (float)total_words / total_lines); } printf("\nLongest line content:\n%s", longest_line); return 0; }
Additional Improvements & Tips
- Handle long lines: If your file has lines longer than
MAX_LINE_LEN,fgetswill truncate them. To handle this, you can read the rest of the truncated line in a loop until you hit a newline. - Use
isspacefrom<ctype.h>: This function checks all whitespace characters (spaces, tabs, newlines, etc.), making your word count logic more robust than checking only spaces and newlines. - Avoid magic numbers: Using
#define MAX_LINE_LEN 102makes your code easier to maintain—if you need to change the buffer size, you only have to update one place. - Float for average: Casting to
floatwhen calculating the average prevents integer division (which would truncate the result). - Input validation: When getting the filename, we use
strcspnto remove the newline character thatfgetsincludes, which avoids issues with invalid filenames. - Null termination safety: When using
strncpy, we manually add a null terminator to prevent buffer overflow if the source string is exactly the length of the destination buffer.
内容的提问来源于stack exchange,提问作者Ciscoeo
相关产品推荐
相关产品推荐

