字符串内指针移动问题:解读代码中buffer内指针的移动逻辑
Understanding Pointer Movement in Your C Code
Let's walk through exactly how the pointers shift and interact in your code—strtok is especially tricky because it relies on internal state, so tracing each line step by step will help clarify what's happening. First, let's fill in the obvious missing parts of your snippet to make the context clear:
#define buf_size 256 FILE *fp = fopen("data.txt", "r"); char buffer[buf_size]; char *read_line_p; char *string_field_in_read_line_p; char *integer_field_in_read_line_p; char *string_field_1; char *string_field_2; while(fgets(buffer, buf_size, fp) != NULL){ read_line_p = malloc((strlen(buffer)+1)*sizeof(char)); strcpy(read_line_p,buffer); string_field_in_read_line_p = strtok(read_line_p,","); integer_field_in_read_line_p = strtok(NULL,","); string_field_1 = malloc((strlen(string_field_in_read_line_p)+1)*sizeof(char)); string_field_2 = malloc((strlen(string_field_in_read_line_p)+1)*sizeof(char)); strcpy(string_field_1, string_field_in_read_line_p); strcpy(string_field_2, string_field_in_read_line_p); // ... rest of your code (freeing memory, processing fields, etc.) }
Now let's break down the pointer movement line by line:
1. fgets(buffer, buf_size, fp)
bufferis a fixed-size character array—its name acts as a pointer to the first character in the array, and this pointer never moves.fgetsreads a line from the file intobuffer, stopping at a newline, end of file, or when it fillsbuf_size-1characters. It adds a null terminator\0at the end of the string.- Only the content inside
bufferchanges here; the pointer itself stays anchored to the start of the array.
2. read_line_p = malloc((strlen(buffer)+1)*sizeof(char))
mallocallocates a new, separate block of memory big enough to hold the string inbuffer(plus space for the null terminator).read_line_pnow points directly to the start of this fresh memory block.
3. strcpy(read_line_p, buffer)
strcpycopies every character frombuffer(starting at its first character) into the memory block pointed to byread_line_p, including the null terminator.read_line_premains pointed to the start of its memory block. The two pointers (bufferandread_line_p) reference completely separate memory—changes to one won't affect the other.
4. string_field_in_read_line_p = strtok(read_line_p, ",")
This is where the critical pointer manipulation happens with strtok:
strtokscans the string starting atread_line_puntil it finds the first,delimiter.- It replaces that
,with a null terminator\0(this modifies the content inread_line_p's memory block!). - It returns a pointer to the start of the first field (the text before the comma)—this is what
string_field_in_read_line_pnow points to. - Behind the scenes,
strtokstores the address of the character immediately after the replaced comma in an internal static variable. This is how it remembers where to resume scanning next time.
5. integer_field_in_read_line_p = strtok(NULL, ",")
- Passing
NULLtostrtoktells it to use the internal saved address from the last call to start scanning. - It finds the next
,(or the end of the string) and replaces it with\0(again modifyingread_line_p's memory). - It returns a pointer to the start of the second field (the text after the first comma)—this is what
integer_field_in_read_line_ppoints to.
6. string_field_1 = malloc(...) and string_field_2 = malloc(...)
- Each
malloccreates a new memory block sized to hold the first field (fromstring_field_in_read_line_p). string_field_1andstring_field_2each point to the start of their own new memory blocks. When youstrcpythe field into them, these pointers stay fixed at the start of their blocks—only the content inside changes.
Key Takeaways
bufferis a fixed array pointer—it never moves, only its content is updated byfgets.read_line_p,string_field_1, andstring_field_2are pointers to dynamically allocated memory; they stay pointed to the start of their blocks unless you explicitly reassign them.strtokmodifies the original string it's given (inread_line_p's memory) and uses internal state to track its position between calls—this is why you shouldn't usestrtokon read-only strings (like literals) or in multi-threaded code.
内容的提问来源于stack exchange,提问作者Zeno Raiser
相关产品推荐
相关产品推荐

