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

字符数组输出内容超出预期?歌曲年份字段打印异常求助

Why does my Song struct's year field print extra characters from the next song's title?

Let's break down exactly what's happening here—this is a classic case of buffer overflow and missing string terminators, which is super easy to miss even when debugging!

The Root Cause

Your year array in the Song struct is too small to hold the full string that fgets reads, including the newline character and the required null terminator (\0). Here's the play-by-play:

  1. How fgets reads your year line
    Your text file has year entries like 1965\n (the \n is the invisible newline at the end of each line). When fgets grabs this line, it includes that newline in the string, then adds a \0 to mark the end of the string. So the full string stored in your line buffer is "1965\n\0"—that's 5 visible characters plus the null terminator, needing 6 total bytes of space.

  2. Your year array can't fit that
    You defined char year[4];—only 4 bytes of space. When you run strcpy(ptr[*nrOfSongs].year, line);, strcpy copies every character until it hits a \0. Since the year array only has 4 slots, it shoves in '1', '9', '6', '5'—but there's no room left for the newline or the \0.

  3. Why printf spills into the next song's title
    C strings depend on that \0 to tell functions like printf where to stop reading. Since your year array doesn't have one, printf just keeps reading memory past the end of year until it finds a \0 somewhere. In your array of Song structs, the memory right after ptr[i].year is the start of ptr[i+1].title—so printf tacks the next song's title onto your year output.

  4. Why debugging looks "correct"
    When you inspect the year array in VS, the debugger only shows you the 4 elements you allocated ('1', '9', '6', '5'). It doesn't show the overflowed newline character or the missing \0, which is why it seems like the value is stored properly even though the string is invalid.

Fixes You Can Use

You've already found one fix (making year the same size as title/artist), but here are two clean approaches:

Option 1: Resize the year array

The minimum size you need is 6 bytes to fit "1965\n\0", but making it 25 like the other fields is totally fine—it's simple and leaves room for any edge cases (like 5-digit years, though that's unlikely). Update your struct:

typedef struct {
    char title[25];
    char artist[25];
    char year[25]; // Match the other fields for consistency
} Song;

Option 2: Strip the newline before copying

If you want to keep year small, remove the newline from the line string before copying it. This way, you only need 5 bytes (for "1965\0"):

// Inside your readFromFile function, right after fgets()
char *newline = strchr(line, '\n');
if (newline != NULL) {
    *newline = '\0'; // Replace newline with null terminator
}

Then you can safely use char year[5]; in your struct.

Quick Side Note

Also, heads up: your initial memory allocation is malloc(sizeof(Song) * 4);—if you ever add more than 4 songs with addSong, you'll hit another buffer overflow. Make sure to add logic to reallocate memory when the array is full!

内容的提问来源于stack exchange,提问作者anderssinho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:18:10