You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. Incorrect loop condition: while(!feof(arquivo)) can cause an extra iteration after the last line is read. Replace it with while(fgets(line, 90, arquivo) != NULL) to properly stop when there's no more data.
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:26:25