C 使用fgets对字符串数组进行排序
我试图创建一个程序,它接受一个整数值,然后决定可以输入的字符串的数量,这是循环两次。一旦输入了两组字符串,我的程序就应该对它们进行排序,并根据它们的长度降序输出它们。当我输出结果时,我没有得到我应该得到的结果C 使用fgets对字符串数组进行排序,c,arrays,C,Arrays,我试图创建一个程序,它接受一个整数值,然后决定可以输入的字符串的数量,这是循环两次。一旦输入了两组字符串,我的程序就应该对它们进行排序,并根据它们的长度降序输出它们。当我输出结果时,我没有得到我应该得到的结果 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int i, num_of_str; //int j; //int a;
#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;
}
#包括
#包括
#包括
内部主(空)
{
int i,n个字符的数量;
//int j;
//INTA;
//int n;
字符输入[100];
scanf(“%d”、&num\u of\u str);
char**strings=malloc(num_of_str*sizeof(char*));
对于(i=0;i
我不知道你为什么要买两套,有一件事我想说的是你正在使用
用于获取字符串数量的scanf和字符串的fgets。因此,您可能会丢失第一个条目
因此。以下是代码中的一些问题:
- 未检查返回指针
。需要检查它,因为如果失败,它的malloc()
指针可以返回void*
。您可以像这样检查NULL
:malloc()
ptr = malloc(......); if (ptr == NULL) { /* handle error */ }
- 未检查
的返回值。这需要检查是否找到scanf()
的1个整数值。您可以通过以下方式进行验证:numstr
if (scanf("%d", &numstr) != 1) { /* handle error */ }
未正确分配。由于这是一个字符串[i]
指针,因此需要分配大量char*
字节,而不是char
指针。您还需要将char*
添加到分配中,以确保它们有足够的空间容纳空终止符+1
。因此,不是:\0
你可以做:strings[i] = malloc(strlen(input) * sizeof(char*));
注意:strings[i] = malloc(strlen(input)+1);
始终为1,因此无需在此处包含它sizeof(char)
- 您的代码不会在第二个
上更新numstr
。如果**strings
最终成为一个更大的字符串,您将访问超出numstr
**字符串限制的字符串,这将导致问题。您可能需要使用此处来调整内存块的大小。一种方法是跟踪第一个
,然后对照第二个numstr
,如果它们不同,调整numstr
字符串的大小。 以下是一个例子:
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\u of_str)
- 必须选中
,因为在读取行失败时,它可能返回fgets()
指针。它还会在缓冲区的末尾追加一个NULL
字符,因此您可能需要在某个时候删除此换行符\n
- 使用
和malloc()
进行的任何堆分配必须在最后使用取消分配realloc()
- 由于
需要void*malloc(size\u t size)
,因此最好在此处使用size\u t
变量size\u 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);
}
#包括
#包括
#包括
#定义线宽100
内部主(空){
字符输入[行大小];
尺寸numstr,上一个numstr,slen;
void*temp=NULL;
printf(“输入集合1的字符串数:\n”);
如果(scanf(“%zu”,&numstr)!=1 | | numstr<1){
fprintf(stderr,“无效值\n”);
退出(退出失败);
}
字符**字符串=malloc(numstr*sizeof(*字符串));
if(strings==NULL){
fprintf(stderr,“无法分配%zu字符串”,numstr);
退出(退出失败);
}
/*第1组*/
对于(大小i=0;i0&&input[slen-1]='\n'){
输入[slen-1]='\0';
}
字符串[i]=malloc(strlen(输入)+1);
if(字符串[i]==NULL){
fprintf(stderr,“无法为字符串\n分配%zu字节”,strlen(输入)+1);
退出(退出失败);
}
strcpy(字符串[i],输入);
}
}
/*跟踪以前的字符串数*/
prev_numstr=numstr;
printf(“输入集合2的字符串数:\n”);
如果(scanf(“%zu”,&numstr)!=1 | | numstr<1){
fprintf(stderr,“无效值\n”);
退出(退出失败);
}
/*仅在大小不同时输入*/
如果(numstr!=上一个numstr){
temp=realloc(字符串,numstr*sizeof(*字符串));
if(temp==NULL){
fprintf(stderr,“无法重新分配%zu空间”,numstr);
退出(退出失败);
}
/*也许临时工可以在这里释放*/
字符串=温度;
}
/*第2组*/
对于(大小i=0;i0&&input[slen-1]='\n'){
输入[slen-1]='\0';
}