简体   繁体   English

在C中没有正确使用strcmp

[英]not using strcmp properly in C

I wrote this method to find the biggest power of 2 that will fit in a given decimal. 我编写了此方法,以找到适合给定十进制数的2的最大幂。 The decimal is in char array format to avoid input overflow error with number storage. 小数点采用char数组格式,以避免在存储数字时出现输入溢出错误。 Powers of 2 are calculated with pow(2, power) format of float ie. 2的幂是使用float的pow(2,power)格式计算的。 8.000000 This number is then sent to a method to remove the period and the 0's that trail. 8.000000然后将这个数字发送到一种方法来删除句点和0的那个尾迹。 ie. 即。 8.000000 turns into 8 8.000000变成8

1  #include <string.h>
2  #include <stdio.h>
3  #include <stdlib.h>
4  #include <memory.h>
5  #include <math.h>
6
7   int i;
16
17  void removeFloatZeros(char *floatvalue)
18  {
19      char *ptr = strchr(floatvalue, '.');
20      *ptr = '\0';
21  }
22
45
173 char *decimalToBinary(char *decimal)
174 {
176     int x;
177     double power = 0;
178     char *binary = malloc(sizeof(char *) * 1024);
179     char *twosPower = malloc(sizeof(char *) * 1024);
180
181     /* What is the greatest power of 2 that will fit into the decimal? */
182     for(x = 0; x <= 30; x++)
183     {
184         power = pow(2.0, x);
185         snprintf(twosPower, 1023, "%f", power);
186         removeFloatZeros(twosPower);
189         printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal));  
190         memset(twosPower, '\0', 1023);
191     }
214 }
215
216 int main(int argc, char*argv[])
217 {
218     char *dec1 = argv[1];
219     decimalToBinary(dec1);
220     return 1;
221 }
222

For example if I input 20 into argv[1] it will output: 例如,如果我在argv [1]中输入20,它将输出:

strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = -1  
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1

Where am I going wrong with this? 我在哪里错呢? Also, ignore the ending condition for the for loop. 同样,忽略for循环的结束条件。 It's supposed to output all 1's before the 6th iteration and all -1's on the 6th and after the 6th iteration. 它应该在第6次迭代之前输出所有1,在第6次以及第6次迭代之后输出所有-1。

strcmp return values: strcmp返回值:

A zero value indicates that both strings are equal. 零值表示两个字符串相等。

A value greater than zero indicates that the first character that does not match has a greater value in str1 than in str2. 大于零的值表示不匹配的第一个字符在str1中的值大于在str2中的值。

And a value less than zero indicates the opposite. 小于零的值表示相反的意思。

Your input: 20 Your first iteration of the loop: twosPower = "1" strcmp("20", "1") 您的输入:20循环的第一次迭代:twosPower =“ 1” strcmp(“ 20”,“ 1”)

The first character doesn't match and has a smaller value in str2 ("1") than in str1 ("2") -> return negative value. 第一个字符不匹配,并且在str2(“ 1​​”)中的值小于在str1(“ 2”)中的值->返回负值。

The rest of the iterations should explain themselves... 其余的迭代应该自己解释一下。

Also, Edit: 另外,编辑:

printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal)); 

Your printf format string states the opposite of what you're doing in the parameter. 您的printf格式字符串表示您在参数中所做的相反的操作。

Edit: 编辑:

str1    str2    
1       20  First char that differs is '1' vs. '2'. '1' (ASCII 49) is smaller than '2' (ASCII 50), 49 - 50 = -1 = return value
2       20  First char that differs is '\0' vs. '0'. '\0' (ASCII 0) is smaller than '0' (ASCII 48), 0 - 48 = -48 = return value
4       20  First char that differs is '4' vs. '2'. '4' (ASCII 52) is greather than '2' (ASCII 50), 52 - 50 = 2 = return value
8       20  First char that differs is '8' vs. '2'. '4' (ASCII 56) is greather than '2' (ASCII 50), 56 - 50 = 6 = return value
16      20  First char that differs is '1' vs. '2'. '1' (ASCII 49) is smaller than '2' (ASCII 50), 49 - 50 = -1 = return value

... and so on ...

Maybe this output helps a bit more 也许这个输出有帮助

Furthermore, your method of finding the greatest power of 2 in a number is flawed since strcmp's return value is just dependent on the FIRST char that differs. 此外,由于strcmp的返回值仅取决于不同的FIRST字符,因此您找到数字最大2的幂的方法存在缺陷。 So strcmp("2", "16") and strcmp("200000000", "16") would always return the same thing. 因此strcmp(“ 2”,“ 16”)和strcmp(“ 200000000”,“ 16”)总是会返回相同的内容。

This cleaned up version of your code produces the output shown: 此代码的清理版本产生的输出如下所示:

$ ./xx 20
strcmp(1, 20) = -1
strcmp(2, 20) = -48
strcmp(4, 20) = 2
strcmp(8, 20) = 6
strcmp(16, 20) = -1
strcmp(32, 20) = 1
strcmp(64, 20) = 4
strcmp(128, 20) = -1
strcmp(256, 20) = 5
strcmp(512, 20) = 3
strcmp(1024, 20) = -1
strcmp(2048, 20) = 52
strcmp(4096, 20) = 2
strcmp(8192, 20) = 6
strcmp(16384, 20) = -1
strcmp(32768, 20) = 1
strcmp(65536, 20) = 4
strcmp(131072, 20) = -1
strcmp(262144, 20) = 6
strcmp(524288, 20) = 3
strcmp(1048576, 20) = -1
strcmp(2097152, 20) = 57
strcmp(4194304, 20) = 2
strcmp(8388608, 20) = 6
strcmp(16777216, 20) = -1
strcmp(33554432, 20) = 1
strcmp(67108864, 20) = 4
strcmp(134217728, 20) = -1
strcmp(268435456, 20) = 6
strcmp(536870912, 20) = 3
strcmp(1073741824, 20) = -1
$

Suffice to say that there are a lot of small changes. 可以说,这里有很多小的变化。

#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

static void removeFloatZeros(char *floatvalue)
{
    char *ptr = strchr(floatvalue, '.');
    *ptr = '\0';
}

static void decimalToBinary(char *decimal)
{
    int x;
    double power = 0;
    char *twosPower = malloc(sizeof(char *) * 1024);

    /* What is the greatest power of 2 that will fit into the decimal? */
    for(x = 0; x <= 30; x++)
    {
        power = pow(2.0, x);
        snprintf(twosPower, 1023, "%f", power);
        removeFloatZeros(twosPower);
        printf("strcmp(%s, %s) = %d\n", twosPower, decimal, strcmp(twosPower, decimal));  
        //printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal));  
        memset(twosPower, '\0', 1023);
    }
    free(twosPower);
}

int main(int argc, char*argv[])
{
    for (int i = 1; i < argc; i++)
        decimalToBinary(argv[i]);
    return 0;
}

Showing the compared values makes things a lot easier to understand. 显示比较值使事情更容易理解。 You need to free memory (or use automatic arrays). 您需要释放内存(或使用自动数组)。 You need to use headers. 您需要使用标题。 The static declarations aren't 100% necessary, but mean I don't get any warnings when I compile under my über-fussy compiler settings. static声明不是100%必需的,但是意味着在über-fussy编译器设置下进行编译时,我不会收到任何警告。

But the key change is printing out the values that are being compared - it makes sense of the numbers from strcmp() . 但是关键的变化是打印出要比较的值-它使strcmp()中的数字有意义。

(Consider adding an appropriate number of leading zeroes before doing your comparison.) (在进行比较之前,请考虑添加适当数量的前导零。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM