0 <= -1如何返回true?

时间:2018-09-13 08:06:11

标签: c

我写了一个小程序作为示例来复制我遇到的问题。该程序以这种方式使用并操纵两行代码:

  1. 它用新行分隔行。
  2. 每行包含一定数量的字母,后跟一个空格(在这种情况下为' '),然后是一个数字。
  3. 它将字母复制到另一个字符串,然后在其中添加'\0'
  4. 它将数字复制到另一个字符。
  5. 它将打印字符串,其中包含复制的字母,而int则是转换后的复制数字。

这是最小的程序:

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

void read(char *text)
{
    // create and initialize the line holder
    int k = 0;
    char line[10];
    line[0] = '\0';
    for (int i = 0;text[i] != '\0';i++)
    {
        if (text[i] == '\n')
        {
            // k now points to the character right after the last assigned one, so put 0 in that place
            line[k] = '\0';

            // initialize data objects that will hold text and number
            char letters[5];
            letters[0] = '\0';
            char val;

            // step through the line, and stop if you 1. reached a blank or 2. reached the end of a line
            int j = 0;
            while (line[j] != ' ' && line[j] != '\t' && j <= (strlen(line) - 1))
            {
                printf("%d <= %ld = %d\n", j, strlen(line) - 1, j <= (strlen(line) - 1));
                if (j == (strlen(line) - 1)) // reached the last character before reaching blank
                    return;
                letters[j] = line[j];
                j++;
            }

            letters[j] = '\0'; // where should be blank place 0

            if (j + 1 == (strlen(line) - 1)) // if the next character is the last character, meaning that the character before the last one is blank
                val = line[j + 1];
            else // there is space in that is not one before the last character
                return; // this is where read("\n") should stop, but withou entering the while loop!

            printf("Word: %s\tVal: %d\n", letters, val - '0');

            // empty the line holder
            line[0] = '\0';
            k = 0;
        }
        else
        {
            // place the ith text character into the kth line character and print them
            line[k] = text[i];
            printf("line[k] = %c\ttext[i] = %c\n", line[k], text[i]);

            // increment k for the next turn
            k++;
        }
    }
}

int main()
{
    char *text = "ABCD 0\nEFGH 1\nIJKL 2\nMNOP 3\nQRST 4\nUVWX 5\nYZ 5\n";
    read(text);
    printf("---------------------------------\n");
    read("\n");
    return 0;
}

还有一些要点,如果程序检测到错误,则应终止而不执行其工作。这些点由return关键字和read(char *text)函数中的注释指示。它们只有两个,所以我也在这里描述它们:

第28行:如果程序检测到当前字符是最后一个字符,则会在此行停止扫描。由于最后一个字符应始终以空格开头,这意味着我们到达了一行的末尾而没有退出while循环(如果我们到达' ''\t'就会发生)。

第38行:如果我们成功退出了while循环,则字符jline之间应为空白。这是因为找到空白后退出了while循环(这也是因为我们以line结束了line[j] = '\0')。这也意味着j+1应该是数字,这是该行中的最后一个字符。如果不是这种情况,我们到达的数字不在数字前面,因此我们退出该函数。


那么,问题出在哪里呢?如您所见,我将两个字符串传递给read(char *text)函数。 read(char *text)可以完美地操作和打印第一个字符串。对于第二个(仅为"\n"),该函数不能很好地工作。我不了解的部分是尽管条件j <= strlen(line) - 1)进入了while循环,但条件1却以某种方式返回了text = "\n"。您可以看到通过运行该程序,它将在第26行上打印该信息。

1 个答案:

答案 0 :(得分:4)

解决此类问题(以及许多其他问题)的方法是打开编译器警告。

$ clang -Wall -Wextra -std=c11 -pedantic-errors k.c
k.c:24:59: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
            while (line[j] != ' ' && line[j] != '\t' && j <= (strlen(line) - 1))
                                                        ~ ^   ~~~~~~~~~~~~~~~~
k.c:26:67: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
                printf("%d <= %ld = %d\n", j, strlen(line) - 1, j <= (strlen(line) - 1));
                                                                ~ ^   ~~~~~~~~~~~~~~~~
k.c:27:23: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
                if (j == (strlen(line) - 1)) // reached the last character before reaching blank
                    ~ ^   ~~~~~~~~~~~~~~~~
k.c:35:23: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
            if (j + 1 == (strlen(line) - 1)) // if the next character is the last character, meaning that t...
                ~~~~~ ^   ~~~~~~~~~~~~~~~~
4 warnings generated.

比较有符号和无符号确实是这里的问题。

为了执行比较,操作数被隐式转换。 j == (strlen(line)(size_t)j == (strlen(line)等效,只是后者不会产生警告。