我正在尝试创建一个程序,该程序采用整数值,然后确定可以输入的字符串数量,这会循环两次。输入两组字符串后,我的程序应该对它们进行排序,并根据它们的长度按降序排列输出它们。当我输出结果时,我没有得到我应该得到的结果。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int i, num_of_str;
//int j;
//int a;
//int n;
char input[100];
scanf("%d", &num_of_str);
char** strings = malloc(num_of_str * sizeof(char*));
for (i = 0; i < num_of_str; i++) {
fgets(input, 100, stdin);
strings[i] = malloc(strlen(input) * sizeof(char*));
strcpy(strings[i], input);
}
scanf("%d", &num_of_str);
for (i = 0; i < num_of_str; i++) {
fgets(input, 100, stdin);
strings[i] = malloc(strlen(input) * sizeof(char*));
strcpy(strings[i], input);
}
int a;
int b;
char* temp;
for (a = 0; a < num_of_str; a++) {
for (b = a + 1; b < num_of_str; b++) {
if (strlen(strings[a]) < (strlen(strings[b]))) {
temp = strings[a];
strings[a] = strings[b];
strings[b] = temp;
}
}
}
for (a = 0; a < num_of_str; a++) {
printf("%s\n", strings[a]);
}
return EXIT_SUCCESS;
}
最佳答案
以下是您的代码中的一些问题:
返回指针
malloc()
没有被检查。需要检查为void*
它的指针可以返回NULL
如果不成功。您可以查看malloc()
像这样:ptr = malloc(......); if (ptr == NULL) { /* handle error */ }
返回值
scanf()
没有被检查。这需要检查numstr
是否有 1 个整数值被找到。您可以这样验证:if (scanf("%d", &numstr) != 1) { /* handle error */ }
strings[i]
没有被正确分配。因为这是char*
指针,需要分配多个char
字节,而不是char*
指针。您还需要添加+1
到您的分配,以确保它们有足够的空间用于空终止符\0
。所以代替:strings[i] = malloc(strlen(input) * sizeof(char*));
你可以这样做:
strings[i] = malloc(strlen(input)+1);
注意:
sizeof(char)
始终为 1,因此无需在此处包含它。您的代码未更新
**strings
在第二个numstr
。如果numstr
这将导致问题最终变得更大,您将访问超出**strings
的限制。您可能需要使用realloc(3)
在这里,调整你的内存块的大小。执行此操作的一种方法是跟踪第一个numstr
,然后对照第二个numstr
进行检查,如果它们不同,则调整strings
的大小。 这是一个例子:prev_numstr = numstr; printf("Enter number of strings for set 2:\n"); if (scanf("%zu ", &numstr) != 1) { /* handle exit */ } if (numstr != prev_numstr) { void *temp = realloc(strings, numstr * sizeof(*strings)); if (temp == NULL) { /* handle exit */ } strings = temp; }
自
scanf()
留下\n
输入缓冲区中的字符,您需要在调用fgets()
之前删除它。您只需添加一个空格即可scanf("%d ", &num_of_str)
,这将消耗缓冲区中剩余的所有空白空间。fgets()
必须检查,因为它可以返回NULL
无法读取行的指针。它还附加了\n
缓冲区末尾的字符,因此您有时可能需要删除此换行符。使用
malloc()
进行的任何堆分配和realloc()
必须用free(3)
取消分配在最后。自
void *malloc(size_t size)
预计size_t
,最好使用size_t
此处改为变量。
由于您的代码没有排序问题,因此这里是一些使用这些点的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINESIZE 100
int main(void) {
char input[LINESIZE];
size_t numstr, prev_numstr, slen;
void *temp = NULL;
printf("Enter number of strings for set 1:\n");
if (scanf("%zu ", &numstr) != 1 || numstr < 1) {
fprintf(stderr, "Invalid value\n");
exit(EXIT_FAILURE);
}
char **strings = malloc(numstr * sizeof(*strings));
if (strings == NULL) {
fprintf(stderr, "Cannot allocate %zu strings\n", numstr);
exit(EXIT_FAILURE);
}
/* Set 1 */
for (size_t i = 0; i < numstr; i++) {
if (fgets(input, LINESIZE, stdin) != NULL) {
slen = strlen(input);
/* removes newline */
if (slen > 0 && input[slen-1] == '\n') {
input[slen-1] = '\0';
}
strings[i] = malloc(strlen(input)+1);
if (strings[i] == NULL) {
fprintf(stderr, "Cannot allocate %zu bytes for string\n", strlen(input)+1);
exit(EXIT_FAILURE);
}
strcpy(strings[i], input);
}
}
/* keeps track of previous number of strings */
prev_numstr = numstr;
printf("Enter number of strings for set 2:\n");
if (scanf("%zu ", &numstr) != 1 || numstr < 1) {
fprintf(stderr, "Invalid value\n");
exit(EXIT_FAILURE);
}
/* only enters if size is different */
if (numstr != prev_numstr) {
temp = realloc(strings, numstr * sizeof(*strings));
if (temp == NULL) {
fprintf(stderr, "Cannot reallocate %zu spaces\n", numstr);
exit(EXIT_FAILURE);
}
/* perhaps temp could could freed here */
strings = temp;
}
/* Set 2 */
for (size_t i = 0; i < numstr; i++) {
if (fgets(input, LINESIZE, stdin) != NULL) {
slen = strlen(input);
if (slen > 0 && input[slen-1] == '\n') {
input[slen-1] = '\0';
}
strings[i] = malloc(strlen(input)+1);
if (strings[i] == NULL) {
fprintf(stderr, "Cannot allocate %zu bytes for string\n", strlen(input)+1);
exit(EXIT_FAILURE);
}
strcpy(strings[i], input);
}
}
/* printing and freeing strings */
for (size_t i = 0; i < numstr; i++) {
printf("%s\n", strings[i]);
free(strings[i]);
strings[i] = NULL;
}
/* freeing double pointer 'strings' itself */
free(strings);
strings = NULL;
exit(EXIT_SUCCESS);
}
注意:我假设您仍然想接受 2 组,并用第二组覆盖第一组,但这确实看起来很奇怪。
关于c - 使用 fget 对字符串数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42552302/