C函数读取文件赋值结构体数组后,主函数输出结果异常求助
Hey there! Let's break down why your code shows weird output in main() even though loader() prints correctly.
The Root Cause
The big issue here is you're storing pointers returned by strtok directly in your struct, but those pointers point to the local array line inside the loader() function. When loader() finishes executing, the memory for line gets deallocated (since it's a local stack variable). By the time you try to access those pointers in main(), they're pointing to invalid memory—this is called a "dangling pointer" problem, which causes the garbage output you're seeing.
Fixes to Try
You have two solid options to fix this, depending on how you want to structure your struct:
Option 1: Use Fixed-Size Character Arrays in the Struct
Instead of using char* for your struct members, define them as fixed-length char arrays. This way, you copy the actual string content into the struct, not just a pointer.
First, update your struct definition:
#define MAX_STRING_LENGTH 50 // Adjust this to fit your needs struct instructionEmMnemonico { char label[MAX_STRING_LENGTH]; char mnemonico[MAX_STRING_LENGTH]; char operando1[MAX_STRING_LENGTH]; char operando2[MAX_STRING_LENGTH]; char operando3[MAX_STRING_LENGTH]; };
Then, in loader(), use strncpy to safely copy the token values into the struct (and always null-terminate to avoid buffer issues):
// Example for copying the label token if (token != NULL) { strncpy(mnemonicoInstru[i].label, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].label[MAX_STRING_LENGTH - 1] = '\0'; // Ensure null termination } else { // If there's no token, set the first character to null to mark it empty mnemonicoInstru[i].label[0] = '\0'; }
Repeat this pattern for mnemonico, operando1, etc.
Option 2: Use Dynamic Memory Allocation
If you prefer to keep using char* in your struct, you need to allocate memory for each string and copy the token content into it. The strdup() function is perfect for this (it combines malloc and strcpy):
In loader(), replace lines like mnemonicoInstru[i].label = token; with:
mnemonicoInstru[i].label = token ? strdup(token) : NULL;
Do this for all string members. Note that strdup requires including <stdlib.h>, and you'll need to free this memory later in main() to avoid leaks:
// In main(), after you're done using the programa array for (int k = 0; k < 500; k++) { free(programa[k].label); free(programa[k].mnemonico); free(programa[k].operando1); free(programa[k].operando2); free(programa[k].operando3); }
Bonus: Fix Other Small Issues
While we're at it, let's fix two other bugs in your code:
- Incorrect loop condition:
while(!feof(arquivo))can cause an extra iteration after the last line is read. Replace it withwhile(fgets(line, 90, arquivo) != NULL)to properly stop when there's no more data. - Broken logical condition:
if(line[0] != ' ' || line[0] != '\n' || line[0] != '\t')will always be true (because a character can't be equal to all three at once). Use&&instead of||if you want to check that the first character isn't any of those whitespace characters.
Example Modified Loader Snippet
Here's how the loop in loader() might look with Option 1 and the fixes:
// Replace your while loop with this while(fgets(line, 90, arquivo) != NULL) { printf("%c-----------\n", line[0]); token = strtok(line, ", \n\t"); // Copy label if (token) { strncpy(mnemonicoInstru[i].label, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].label[MAX_STRING_LENGTH - 1] = '\0'; printf("%s\n", mnemonicoInstru[i].label); } else { mnemonicoInstru[i].label[0] = '\0'; } // Copy mnemonico token = strtok(NULL, ", \n\t"); if (token) { strncpy(mnemonicoInstru[i].mnemonico, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].mnemonico[MAX_STRING_LENGTH - 1] = '\0'; printf("%s\n", mnemonicoInstru[i].mnemonico); } else { mnemonicoInstru[i].mnemonico[0] = '\0'; } // Repeat for operando1, operando2, operando3 token = strtok(NULL, ", \n\t"); if (token) { strncpy(mnemonicoInstru[i].operando1, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].operando1[MAX_STRING_LENGTH - 1] = '\0'; printf("%s\n", mnemonicoInstru[i].operando1); } else { mnemonicoInstru[i].operando1[0] = '\0'; } token = strtok(NULL, ", \n\t"); if (token) { strncpy(mnemonicoInstru[i].operando2, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].operando2[MAX_STRING_LENGTH - 1] = '\0'; printf("%s\n", mnemonicoInstru[i].operando2); } else { mnemonicoInstru[i].operando2[0] = '\0'; } token = strtok(NULL, ", \n\t"); if (token) { strncpy(mnemonicoInstru[i].operando3, token, MAX_STRING_LENGTH - 1); mnemonicoInstru[i].operando3[MAX_STRING_LENGTH - 1] = '\0'; printf("%s\n", mnemonicoInstru[i].operando3); } else { mnemonicoInstru[i].operando3[0] = '\0'; } i++; }
Once you implement one of these fixes, your main() function should print the correct values from the struct array!
内容的提问来源于stack exchange,提问作者Rafael Higa

