我刚用C编写了一个相当简单的程序来查找smallest word
和largest word
。我有3个变量如下:
char smallest[20]; // smallest word
char largest[20]; // largest word
char word[20]; // the word entered by user
然后我会提示用户输入他想要的任何单词:
while (1) {
printf("Enter a word: ");
while((ch = getchar()) != '\n') {
word[i++] = ch;
}
}
然后,我会将word
与smallest
和largest
进行比较,以便获得在用户输入的字词中找到最小和最大字词的结果。
if (strcmp(word, smallest) < 0) {
strcpy(smallest, word);
}
if (strcmp(word, largest) > 0) {
strcpy(largest, word);
}
如果用户只是输入而没有输入任何单词,程序将终止。
该程序正确找到largest
字,但我的问题是找到smallest
字。
如果您想要复制/粘贴来测试它,这是整个程序。
#include <stdio.h>
#include <string.h>
int main(void) {
char smallest[20] = "";
char largest[20] = "";
char word[20] = "";
while (1) {
int i = 0;
char ch;
strcpy(word, "");
printf("Enter a word: ");
while((ch = getchar()) != '\n') {
word[i++] = ch;
}
if (strcmp(word, smallest) < 0) {
strcpy(smallest, word);
}
if (strcmp(word, largest) > 0) {
strcpy(largest, word);
}
if (strlen(word) == 0) break;
}
printf("Smallest word: %s\n", smallest);
printf("Largest word: %s\n", largest);
return 0;
}
请您告诉我如何修改它以正确找到smallest
和largest
字。
答案 0 :(得分:4)
这个循环至少有四个问题:
while((ch = getchar()) != '\n') {
word[i++] = ch;
}
首先,它可以覆盖数组之外的内存,其次你必须附加终结零的字符串。您还要将结果保存到char
,但getchar()
会返回int
,并且您没有测试EOF
,但您应该(并且至关重要的是使用int ch;
1}}这样您就可以准确地测试EOF
)。
使用函数fgets
代替getchar
(但请记住它在输出中包含换行符)。
或者按以下方式重写循环
while( i < 19 && (ch = getchar()) != '\n' && ch != EOF) {
word[i++] = ch;
}
word[i] = '\0';
考虑到代码中似乎存在拼写错误。至少我没有看到声明
smallest_word
和largest_word
。
答案 1 :(得分:3)
你的一个问题是,空字符串比其他所有字符串都要小,所以找到最小字符串的代码会正确返回初始化它的空字符串。
由于没有特殊字符串比其他所有字符串都要大,所以你需要使用你得到的第一个字符串作为初始化:
for(int i = 0; ; i++) {
//code to read a string
if(!i) {
//First time: the current string is definitely the smallest and the largest one.
strcpy(smallest, word);
strcpy(largest, word);
} else {
if (strcmp(word, smallest_word) < 0) strcpy(smallest, word);
if (strcmp(word, largest_word) > 0) strcpy(largest, word);
}
}
旁注:
使用固定大小的缓冲区来存储来自用户输入的字符串通常不是一个好主意。迟早你将获得超过缓冲区大小的输入。更好地使用动态分配的字符在你的情况下,你可以这样做:
#include <stdio.h>
#include <string.h>
int main(void) {
char* smallest = NULL, *largest = NULL, *word = NULL;
for(int i = 0; ; i++) {
printf("Enter a word: ");
size_t bufferSize = 0;
ssize_t stringSize = getline(&word, &bufferSize, stdin); //this returns a malloced string with the entire line in word
if(stringSize <= 0) break; //This also catches end of file.
word[stringSize - 1] = 0; //getline() includes the newline in the string, remove it
if(!i) {
//First time: the current string is definitely the smallest and the largest one.
smallest = strdup(word);
largest = strdup(word);
} else {
if (strcmp(word, smallest) < 0) {
free(smallest);
smallest = strdup(word);
}
if (strcmp(word, largest) > 0) {
free(largest);
largest = strdup(word);
}
}
free(word);
}
printf("Smallest word: %s\n", smallest);
printf("Largest word: %s\n", largest);
free(smallest);
free(largest);
return 0;
}
用户可以在此代码中抛出长度为兆字节的字符串,并且可以轻松处理它们。
答案 2 :(得分:1)
使用strlen()
代替strcmp()
来查看哪个字段更长。
strcmp()
将比较两个字符串是否相同,strlen()
将得到长度。