字符数组输出内容超出预期?歌曲年份字段打印异常求助
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:
How
fgetsreads your year line
Your text file has year entries like1965\n(the\nis the invisible newline at the end of each line). Whenfgetsgrabs this line, it includes that newline in the string, then adds a\0to mark the end of the string. So the full string stored in yourlinebuffer is"1965\n\0"—that's 5 visible characters plus the null terminator, needing 6 total bytes of space.Your
yeararray can't fit that
You definedchar year[4];—only 4 bytes of space. When you runstrcpy(ptr[*nrOfSongs].year, line);,strcpycopies every character until it hits a\0. Since theyeararray only has 4 slots, it shoves in'1','9','6','5'—but there's no room left for the newline or the\0.Why
printfspills into the next song's title
C strings depend on that\0to tell functions likeprintfwhere to stop reading. Since youryeararray doesn't have one,printfjust keeps reading memory past the end ofyearuntil it finds a\0somewhere. In your array ofSongstructs, the memory right afterptr[i].yearis the start ofptr[i+1].title—soprintftacks the next song's title onto your year output.Why debugging looks "correct"
When you inspect theyeararray 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

