C语言文本替换程序问题求助:仅首个单词完成替换
Let's break down why only the first word is getting replaced in your code—there are several critical issues in your logic and structure, and we'll fix them step by step:
Key Problems in Your Current Code
You process the input text file once per dictionary entry (only the first pass works)
Your loop runs like this: read one dictionary entry → scan the entire input file → repeat. But after the first pass throughtest.txt, the file pointerfpis already at the end of the file. All subsequent dictionary loops won't read any new content, so those translations never get applied.You don't store all dictionary entries
Yourtabarray only holds the current entry's Polish/English pair. You never save all translations to check against later—so even if you fixed the file pointer issue, you'd only ever replace one word per run.Incorrect use of
feof()feof()only returns true after a read operation fails to find more data. Usingwhile(!feof(file))can lead to extra, incorrect loop iterations. It's better to check the return value of your read functions directly.Missing handling for the final word
If your input file ends with a word (not a space), your code never processes that last word—since you only trigger word processing when you hit a space.Small
fscanf()bug
When callingfscanf(slownik,"%s",&liniatekstu);, ifliniatekstuis a char array, you shouldn't use&—the array name itself acts as a pointer to its first element.
Fixed Code Implementation
We'll rewrite the code to fix these issues: first, store all dictionary entries in memory, then process the input text file once, checking each word against all stored translations.
#include <stdio.h> #include <string.h> #include <ctype.h> // Structure to hold Polish-English word pairs typedef struct { char polish[1000]; char english[1000]; } DictionaryEntry; #define MAX_ENTRIES 100 // Adjust based on your expected dictionary size int main() { DictionaryEntry dict[MAX_ENTRIES]; int dict_count = 0; char line[1000]; FILE *slownik = fopen("slownik.txt", "r"); FILE *fp = fopen("test.txt", "r"); if (!slownik || !fp) { printf("Error opening file!\n"); return 1; } // Step 1: Read all dictionary entries into memory while (fgets(line, sizeof(line), slownik) != NULL) { // Split line into individual word pairs (split by commas) char *pair = strtok(line, ","); while (pair != NULL) { // Split each pair into Polish and English words (split by colon) char *pl_word = strtok(pair, ":"); char *en_word = strtok(NULL, " :"); // Ignore spaces around colon if (pl_word && en_word && dict_count < MAX_ENTRIES) { // Trim leading/trailing whitespace from words // Polish word trim while (isspace((unsigned char)*pl_word)) pl_word++; char *pl_end = pl_word + strlen(pl_word) - 1; while (pl_end > pl_word && isspace((unsigned char)*pl_end)) pl_end--; *(pl_end + 1) = '\0'; // English word trim while (isspace((unsigned char)*en_word)) en_word++; char *en_end = en_word + strlen(en_word) - 1; while (en_end > en_word && isspace((unsigned char)*en_end)) en_end--; *(en_end + 1) = '\0'; // Save to dictionary strncpy(dict[dict_count].polish, pl_word, sizeof(dict[dict_count].polish)-1); strncpy(dict[dict_count].english, en_word, sizeof(dict[dict_count].english)-1); dict_count++; } pair = strtok(NULL, ","); } } // Step 2: Process the input text file char slowo[1000]; int idx = 0; int c; while ((c = fgetc(fp)) != EOF) { if (!isspace((unsigned char)c)) { if (idx >= sizeof(slowo)-1) { printf("Error - word exceeds 1000 characters\n"); idx = 0; continue; } slowo[idx++] = c; } else { if (idx > 0) { slowo[idx] = '\0'; idx = 0; // Check if word exists in dictionary int found = 0; for (int i = 0; i < dict_count; i++) { if (strcmp(slowo, dict[i].polish) == 0) { printf("%s ", dict[i].english); found = 1; break; } } if (!found) { printf("%s ", slowo); } } // Print the original space printf("%c", c); } } // Handle the final word (if file ends without a space) if (idx > 0) { slowo[idx] = '\0'; int found = 0; for (int i = 0; i < dict_count; i++) { if (strcmp(slowo, dict[i].polish) == 0) { printf("%s", dict[i].english); found = 1; break; } } if (!found) { printf("%s", slowo); } } fclose(slownik); fclose(fp); return 0; }
What This Fixed Code Does
- Stores all dictionary entries first, so we can check every word against every translation pair.
- Processes the input file once, avoiding the file pointer issue from your original code.
- Handles the final word in the input file, even if there's no trailing space.
- Trims whitespace from dictionary entries (so spaces around colons/commas don't break matches).
- Uses safer file reading by checking the return value of
fgets()andfgetc()instead of relying onfeof().
Test this with your sample files, and it should output the expected: mother poszla z father on zakupy
内容的提问来源于stack exchange,提问作者P.Manek

