我需要用 C 语言编写一个程序,接收数字 N 和 N×单词(字符串)。找到具有最少字符数的单词,将所有其他单词减少到最小字符大小,然后按照给定的相反顺序打印它们。但打印后什么也没有出现。就像打印空格一样。
#include <stdio.h>
#include <string.h>
int main() {
int N, min, i;
char S[100][51], gra[51];
scanf("%d", &N);
if (N < 1 || N > 100) {
printf("Wrong Input");
return 1;
}
min = 52;
for (i = 0; i < N; i++) {
fgets(S[i], 51, stdin);
S[i][strcspn(S[i], "\n")] = '\0';
if (strlen(S[i]) < min) {
min = strlen(S[i]);
}
}
for (i = 0; i < N; i++) {
S[i][min + 1] = '\0';
}
i = N - 1;
do {
strncpy(gra, S[i], min + 1);
printf("%s ", gra);
i--;
} while (i >= 0);
return 0;
}
代码的 main 问题是
scanf("%d", &N);
在读取 N
值后在输入缓冲区中留下换行符。因此,后续 for
循环的第一次运行读取空字符串,因此 min
值将设置为零。这里详细讨论了这个问题: scanf() 将换行符留在缓冲区中。清除此问题的一个简单方法是在读取 scanf("%*c");
和开始循环之间添加一条 N
行,但是链接问题的答案中还给出了其他方法。
修复后,您仍然遇到一些问题:请注意,在 C 中数组索引从 zero 开始;因此,要将字符串截断为仅
min
字符,您需要在 nul
处添加 '\0'
终止符 (S[i][min]
),在 S[i][min+1]
处添加 not,就像您所做的那样。
此外,添加终止符后,您不需要使用
strncpy
– 一个简单的 strcpy
就足够了。
这是包含上述修复的代码版本:
#include <stdio.h>
#include <string.h>
int main(void)
{
int N, i;
char S[100][51], gra[51];
scanf("%d", &N);
if (N < 1 || N > 100) {
printf("Wrong Input");
return 1;
}
scanf("%*c"); // Clear leftover newline from input buffer
size_t min = 52; // The "size_t" type is a better fit for `strlen`
for (i = 0; i < N; i++) {
fgets(S[i], 51, stdin);
S[i][strcspn(S[i], "\n")] = '\0';
if (strlen(S[i]) < min) {
min = strlen(S[i]);
}
}
for (i = 0; i < N; i++) {
S[i][min] = '\0'; // Array indexes start at zero, so add null at [min], not [min+1].
}
i = N - 1;
do {
strcpy(gra, S[i]); // Don't need strncpy: a nul terminator has been added to limit length
printf("%s ", gra);
i--;
} while (i >= 0);
return 0;
}