C语言字符串逆序复制方法及数组旋转失效问题排查
Hey there! Let's break down your C programming questions one by one—you've got a few distinct puzzles here, so we'll tackle them step by step:
1. Copying characters from a string's end to start
To copy a string in reverse order, you just need to iterate from the last valid character (right before the null terminator '\0') back to the first, then build your new string. Here's a reliable implementation:
#include <stdio.h> #include <string.h> #include <stdlib.h> char* reverse_copy(const char* original) { if (!original) return NULL; // Guard against NULL input size_t len = strlen(original); // Allocate memory for reversed string (plus null terminator) char* reversed = (char*)malloc(len + 1); if (!reversed) return NULL; // Check for malloc failure for (size_t i = 0; i < len; i++) { // Grab the original string's (last - i)th character reversed[i] = original[len - 1 - i]; } reversed[len] = '\0'; // Don't forget the null terminator—critical for valid C strings! return reversed; } // Example usage int main() { const char* str = "hello world"; char* rev = reverse_copy(str); if (rev) { printf("Original: %s\nReversed copy: %s\n", str, rev); free(rev); // Always free allocated memory to avoid leaks! } return 0; }
Key reminders:
- Always validate inputs and memory allocations to avoid crashes.
- The null terminator is non-negotiable—without it, your "string" is just a random char array.
2. Fixing your string array reordering failure
Your goal is to turn {"aaa", "bb", "cccc", "d"} into {"cccc", "d", "aaa", "bb"}. Let's first diagnose why your index swap attempt didn't work:
Common mistakes people make here:
- Swapping string contents instead of pointers: If you used
strcpyto swap element contents (e.g.,strcpy(arr[0], arr[2])), this fails because the buffers are different sizes. "cccc" needs 5 bytes (plus null terminator), while "aaa" only has 4—this causes buffer overflow and corrupted data. - Overwriting values before using them: If you tried swapping pairs without temporary storage (e.g.,
arr[0] = arr[2]; arr[2] = arr[0];), you'd lose the originalarr[0]value before you can assign it toarr[2].
Correct approach (swap pointers, not contents)
Since this is an array of pointers, you just need to reassign the pointers directly. Here's a simple way:
#include <stdio.h> int main() { const char* arr[] = {"aaa", "bb", "cccc", "d"}; const char* temp[4]; // Temporary array to hold the new order // Move last two elements to front, then first two to the end temp[0] = arr[2]; temp[1] = arr[3]; temp[2] = arr[0]; temp[3] = arr[1]; // Update original array (or just use temp directly if you don't need to modify the original) for (int i = 0; i < 4; i++) { arr[i] = temp[i]; } // Verify output for (int i = 0; i < 4; i++) { printf("%s ", arr[i]); } // Output: cccc d aaa bb return 0; }
If you want to do this in-place without a temp array, you can use a single temporary pointer to hold values while swapping, but the temp array method is clearer for this specific reordering.
3. Fixing your broken string rotation code
Your current rotation code has several critical issues preventing it from working as expected. Let's go through them and fix the whole thing:
Problems in your original code:
- Unspecified
N: You usemalloc(sizeof(char)*N)but never defineN—this will cause compiler errors or buffer overflows ifNis too small. gets()is unsafe/deprecated: It doesn't check input length, so it can write past your allocated buffer and crash your program. Usefgets()instead.rewind(stdin)is unreliable: It doesn't consistently clear the input buffer afterscanf. Use a loop to discard leftover characters instead.- Potential
rotatefunction flaws: If yourrotatefunction isn't modifying the string in-place correctly, it won't affect the original string inmain.
Fixed rotation code
Here's the corrected version with all issues addressed, plus a working in-place rotate function:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define N 100 // Define a reasonable buffer size for input // Helper function to reverse a substring void reverse(char* str, int start, int end) { while (start < end) { char temp = str[start]; str[start] = str[end]; str[end] = temp; start++; end--; } } // Rotate string right by r positions (in-place) void rotate(char* str, int len, int r) { if (len == 0 || r % len == 0) return; // No rotation needed r = r % len; // Handle rotations larger than string length // Reversal method for efficient rotation reverse(str, 0, len-1); reverse(str, 0, r-1); reverse(str, r, len-1); } int main() { char *str = (char*)malloc(sizeof(char)*N); if (!str) { printf("Memory allocation failed!\n"); return 1; } int r; printf("Please enter the number of rotations: "); if (scanf("%d", &r) != 1) { printf("Invalid input!\n"); free(str); return 1; } // Clear leftover newline from scanf input int c; while ((c = getchar()) != '\n' && c != EOF); printf("Enter the string to rotate: "); fgets(str, N, stdin); // Remove newline character added by fgets size_t len = strlen(str); if (len > 0 && str[len-1] == '\n') { str[len-1] = '\0'; len--; } rotate(str, len, r); printf("Rotated string: %s\n", str); free(str); // Clean up allocated memory return 0; }
内容的提问来源于stack exchange,提问作者מחמוד עראבי

