[英]Problems with STRCPY and STRCMP when finding the smallest and largest problems
我正在編寫一個程序,根據KNKing問題中的字典順序找到最小和最大的單詞。 找到一個單詞中最大和最小的單詞,直到用戶輸入一個4個字母的單詞。
首先,我使用strcmp來比較輸入字與最大或最小。 然后使用strcpy將輸入字符串復制到最大或最小。
#include <string.h>
#include <stdio.h>
main()
{
char inputStr[20] ;
char max[20];
char min[20];
int length =0;
do
{
printf("pls, input your string: ");
gets(inputStr);
if(strcmp(inputStr,max) > 0)
strcpy(max,inputStr);
if (strcmp(inputStr,min) < 0)
strcpy(min,inputStr);
length = strlen(inputStr);
}
while (length != 4);
printf("largest word is: %s\n",max);
printf("smallest word is: %s",min);
}
例如。
Enter Word : Cat
Enter Word : Dog
Enter Word : penguin
Enter Word : bear
the smallest word is bear
the largest word is penguin
但是,在運行程序時,最大的單詞始終是特殊字符,最小的單詞始終是正確的。 我的程序顯示了結果
the largest word is:
the smallest word is: bear
我懷疑主要的問題是max或min總是不正確的,因為它們是空的(或充滿垃圾)開始。 您應該將代碼重新格式化為樣式:
min = max = initial-input()
length = len(min)
while (length != 4)
do stuff
我還建議使用fgets()或getline()來讀取輸入,以防萬一你只留出20個字符而只留出20個字符。與strcpy()相同,它應該被替換為strncpy()案件。 所以結果看起來像:
...
fgets(inputStr, 20, stdin);
strncpy(max, inputStr, 20);
strncpy(min, inputStr, 20);
length = strlen(inputStr);
while(length != 4) {
...
}
問題是由於未初始化的char數組。 這(在strcmp
使用它)是未定義的行為。 從邏輯上講,您的代碼也無法正常運行。 strcasecmp
不是標准的一部分 - 它是POSIX的東西。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXLETTER 20
int main(void)
{
char inputStr[MAXLETTER] ;
char max[MAXLETTER];
char min[MAXLETTER];
size_t length =0;
bool flag = true;
do
{
printf("pls, input your string: ");
if( fgets(inputStr,sizeof inputStr,stdin) == NULL){
fprintf(stderr, "%s\n", "Error in input");
exit(1);
}
inputStr[strcspn(inputStr,"\n")]='\0';
if(flag){
strncpy(max,inputStr,MAXLETTER-1);
strncpy(min,inputStr,MAXLETTER-1);
max[MAXLETTER-1]=0;
min[MAXLETTER-1]=0;
flag = false;
}
if(strcasecmp(inputStr,max) > 0){
strncpy(max,inputStr,MAXLETTER-1);
max[MAXLETTER-1]=0;
}
if (strcasecmp(inputStr,min) < 0){
strncpy(min,inputStr,MAXLETTER-1);
min[MAXLETTER-1]=0;
}
length = strlen(inputStr);
}
while (length != 4);
printf("largest word is: %s\n",max);
printf("smallest word is: %s",min);
return 0;
}
使用gcc -Wall -Wextra -Werror progname.c
編譯你的程序,它會告訴你哪里出錯了。
一件事, 不要使用gets()
。
它被稱為
Undefined behavior
。 它可能會工作一段時間,也可能不會。 這是關於它的事情。 在比較時沒有初始化,則沒有定義行為。 它可能會出現一些錯誤,可能會令人驚訝地給出正確的結果。
您沒有按比例初始化 max
或min
因此在第一次比較它們時它們將被設置為任意值。
無論比較如何 ,您只需將它們設置為第一個單詞即可解決此問題:
int firstTime = 1;
do
{
printf("Please input your string: ");
gets(inputStr);
if (firstTime || (strcmp(inputStr, max) > 0))
strcpy(max, inputStr);
if (firstTime || (strcmp(inputStr, min) < 0))
strcpy(min, inputStr);
firstTime = 0;
length = strlen(inputStr);
}
而且,順便說一句,有一個原因是為什么不推薦使用gets
並從標准中刪除,如果你使用這個函數,就沒有辦法防止緩沖區溢出。 這里可以找到更多細節,其中還包括一個非常方便的問題解決方案。
修訂
#include <stdio.h>
#include <string.h>
#define N 20
int main( void )
{
char max[N];
char min[N];
char (*ch)[N];
char inputStr[N] ;
int length = 0;
fgets(inputStr, sizeof(inputStr), stdin);
// Technique from https://stackoverflow.com/a/28462221/701302
inputStr[strcspn(inputStr, "\n")] = 0;
// Set both max and min to initial input in order to ...
strcpy(max,inputStr);
strcpy(min,inputStr);
do
{
fgets(inputStr, sizeof(inputStr), stdin);
inputStr[strcspn(inputStr, "\n")] = 0;
// ... now have basis for valid comparison
if (strcmp(inputStr,max) > 0){
strcpy(max,inputStr);
}
else
if ( strcmp(inputStr,min) < 0){
strcpy(min,inputStr);
}
length = strlen(inputStr);
} while (length != 4);
printf("largest word is: %s\n",max);
ch = &min;
if (strcmp(ch,"") == 0){
ch = "[empty string]";
}
printf("smallest word is: %s",ch);
}
查看實時代碼 。
注意:使用fgets()比使用gets()更安全。 get()危險的原因是本文中潛在緩沖區溢出的b / c。 但是,使用fgets(),輸入可能會以換行符結束,因此您需要刪除它。 盡管你可能會使用strtok(),但它的設計並沒有考慮到這種可能性,因為chux評論說,如果用戶的輸入包含換行符,則不夠。
我再次修改了這個答案,從這里得到了一個提示。 該技術利用strcspn()返回str1中的字符數而不是str2中的字符數。因此,每當輸入包含一個或多個可打印字符或換行符時,換行符都會被替換。 因此,我在ideaone.com上修改了代碼和輸入。 所以,現在輸出反映最大的單詞是企鵝 ,最小的單詞是空字符串。 但是,如果您運行僅使用代碼原始輸入的OP,那么結果將是企鵝和熊分別作為最大和最小字字典順序發言。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.