array subscript is of type ‘char’ warning not sure how to clear

huangapple go评论76阅读模式
英文:

array subscript is of type 'char' warning not sure how to clear

问题

以下是代码中出现的警告信息的翻译:

A32.c:42:13: 警告: 数组下标的类型为'char' [-Wchar-subscripts]
       table[pattern[i]] = m - 1 - i;
            ^~~~~~~~~~~


A32.c:55:18: 警告: 数组下标的类型为'char' [-Wchar-subscripts]
       i += table[text[i]];
                 ^~~~~~~~


A32.c:74:13: 警告: 数组下标的类型为'char' [-Wchar-subscripts]
       table[pattern[i]] = m - 1 - i;
            ^~~~~~~~~~~


A32.c:88:22: 警告: 数组下标的类型为'char' [-Wchar-subscripts]
           i += table[text[i]];

代码如下:

int horspool_search(char* text, char* pattern) {
   int n = strlen(text);
   int m = strlen(pattern);
   int count = 0;
   int shifts = 0;

   // 创建一个位移表
   int table[256];
   for (int i = 0; i < 256; i++) {
       table[i] = m;
   }
   for (int i = 0; i < m - 1; i++) {
       table[pattern[i]] = m - 1 - i;
   }

   int i = m - 1;
   while (i < n) {
       int j = 0;
       while (j < m && text[i - j] == pattern[m - 1 - j]) {
           j++;
       }
       shifts++;
       if (j == m) {
           count++;
       }
       i += table[text[i]];
   }
   printf("Horspool算法位移次数:%d\n", shifts);
   return count;
}

// 实现Boyer-Moore算法的函数
int boyer_moore_search(char* text, char* pattern) {
   int n = strlen(text);
   int m = strlen(pattern);
   int count = 0;
   int shifts = 0;

   // 创建一个位移表
   int table[256];
   for (int i = 0; i < 256; i++) {
       table[i] = m;
   }
   for (int i = 0; i < m - 1; i++) {
       table[pattern[i]] = m - 1 - i;
   }

   int i = m - 1;
   while (i < n) {
       int j = 0;
       while (j < m && text[i - j] == pattern[m - 1 - j]) {
           j++;
       }
       shifts++;
       if (j == m) {
           count++;
           i += m;
       } else {
           i += table[text[i]];
       }
   }
   printf("Boyer-Moore算法位移次数:%d\n", shifts);
   return count;
}
英文:

I was hoping to get some help with warning coming up on my code, it does run correctly I cannot seem to clear them.
the errors are:

A32.c:42:13: warning: array subscript is of type &#39;char&#39; [-Wchar-subscripts]
table[pattern[i]] = m - 1 - i;
^~~~~~~~~~~
A32.c:55:18: warning: array subscript is of type &#39;char&#39; [-Wchar-subscripts]
i += table[text[i]];
^~~~~~~~
A32.c:74:13: warning: array subscript is of type &#39;char&#39; [-Wchar-subscripts]
table[pattern[i]] = m - 1 - i;
^~~~~~~~~~~
A32.c:88:22: warning: array subscript is of type &#39;char&#39; [-Wchar-subscripts]
i += table[text[i]];

The code is:

int horspool_search(char* text, char* pattern) {
int n = strlen(text);
int m = strlen(pattern);
int count = 0;
int shifts = 0;
// Create a shift table
int table[256];
for (int i = 0; i &lt; 256; i++) {
table[i] = m;
}
for (int i = 0; i &lt; m - 1; i++) {
table[pattern[i]] = m - 1 - i;
}
int i = m - 1;
while (i &lt; n) {
int j = 0;
while (j &lt; m &amp;&amp; text[i - j] == pattern[m - 1 - j]) {
j++;
}
shifts++;
if (j == m) {
count++;
}
i += table[text[i]];
}
printf(&quot;Horspool&#39;s algorithm shifts: %d\n&quot;, shifts);
return count;
}
// Function to implement the Boyer-Moore algorithm
int boyer_moore_search(char* text, char* pattern) {
int n = strlen(text);
int m = strlen(pattern);
int count = 0;
int shifts = 0;
// Create a shift table
int table[256];
for (int i = 0; i &lt; 256; i++) {
table[i] = m;
}
for (int i = 0; i &lt; m - 1; i++) {
table[pattern[i]] = m - 1 - i;
}
int i = m - 1;
while (i &lt; n) {
int j = 0;
while (j &lt; m &amp;&amp; text[i - j] == pattern[m - 1 - j]) {
j++;
}
shifts++;
if (j == m) {
count++;
i += m;
} else {
i += table[text[i]];
}
}
printf(&quot;Boyer-Moore algorithm shifts: %d\n&quot;, shifts);
return count;
}

I am not too sure what change needs to be made, assuming it is something small and the same for all 4 warnings

答案1

得分: 1

以下是翻译好的部分:

警告的原因是char类型可能根据目标平台和编译器配置而带符号或无符号。忽视这一点并将char值用于索引表,就像它们从不为负一样,这是一个常见的可移植性问题。

在您的代码中,您确实假定char是无符号的,范围是0255。尽管char类型几乎总是8位(除了一些晦涩的DSP和古老的大型机),但许多编译器将其视为带符号的,范围为-128127。在这种系统上,如果遇到任何超出范围0127char值,即如果字符串包含非ASCII字节,例如UTF-8编码的U+007F之外的字符,则您的代码将具有未定义行为。

您可以通过将char值强制转换为unsigned char,或者使用unsigned char *指针来操作充当索引值的字符数组来避免这个问题。

这是一个修改过的版本:

#include <limits.h>;

size_t horspool_search(const char *text, const char *pattern) {
    size_t n = strlen(text);
    size_t m = strlen(pattern);
    size_t count = 0;
    size_t shifts = 0;

    if (m == 0)
        return 0;

    // 创建一个移位表
    size_t table[UCHAR_MAX + 1];
    for (size_t i = 0; i < UCHAR_MAX + 1; i++) {
        table[i] = m;
    }
    for (size_t i = 0; i < m - 1; i++) {
        table[(unsigned char)pattern[i]] = m - 1 - i;
    }

    size_t i = m - 1;
    while (i < n) {
        size_t j = 0;
        while (j < m && text[i - j] == pattern[m - 1 - j]) {
            j++;
        }
        shifts++;
        if (j == m) {
            count++;
        }
        i += table[(unsigned char)text[i]];
    }
    printf("Horspool's algorithm shifts: %zu\n", shifts);
    return count;
}

// 实现Boyer-Moore算法的函数
size_t boyer_moore_search(const char *text, const char *pattern) {
    size_t n = strlen(text);
    size_t m = strlen(pattern);
    size_t count = 0;
    size_t shifts = 0;

    if (m == 0)
        return 0;

    // 创建一个移位表
    size_t table[UCHAR_MAX + 1];
    for (size_t i = 0; i < UCHAR_MAX + 1; i++) {
        table[i] = m;
    }
    for (size_t i = 0; i < m - 1; i++) {
        table[(unsigned char)pattern[i]] = m - 1 - i;
    }

    size_t i = m - 1;
    while (i < n) {
        size_t j = 0;
        while (j < m && text[i - j] == pattern[m - 1 - j]) {
            j++;
        }
        shifts++;
        if (j == m) {
            count++;
            i += m;
        } else {
            i += table[(unsigned char)text[i]];
        }
    }
    printf("Boyer-Moore algorithm shifts: %zu\n", shifts);
    return count;
}
英文:

The reason for this warning is the type char may be signed or unsigned depending on the target platform and the compiler configuration. It is a common portability issue to ignore this and use char values to index into tables as if they are never negative.

In your code, you indeed assume that char is unsigned and has a range of 0 to 255. While the type char is almost always 8-bit (except for some obscure DSPs and antique mainframes), many compilers consider it signed with a range of -128 to 127. On such systems, your code would have undefined behavior if any of the char values encountered are outside the range 0 to 127, ie: if the strings contain non-ASCII bytes such as UTF-8 encoded glyphs beyond U+007F.

You can avoid this issue by casting the char values as unsigned char or by using unsigned char * pointers to manipulate arrays of characters that serve as index values.

Here is a modified version:

#include &lt;limits.h&gt;
size_t horspool_search(const char *text, const char *pattern) {
size_t n = strlen(text);
size_t m = strlen(pattern);
size_t count = 0;
size_t shifts = 0;
if (m == 0)
return 0;
// Create a shift table
size_t table[UCHAR_MAX + 1];
for (size_t i = 0; i &lt; UCHAR_MAX + 1; i++) {
table[i] = m;
}
for (size_t i = 0; i &lt; m - 1; i++) {
table[(unsigned char)pattern[i]] = m - 1 - i;
}
size_t i = m - 1;
while (i &lt; n) {
size_t j = 0;
while (j &lt; m &amp;&amp; text[i - j] == pattern[m - 1 - j]) {
j++;
}
shifts++;
if (j == m) {
count++;
}
i += table[(unsigned char)text[i]];
}
printf(&quot;Horspool&#39;s algorithm shifts: %zu\n&quot;, shifts);
return count;
}
// Function to implement the Boyer-Moore algorithm
size_t boyer_moore_search(const char *text, const char *pattern) {
size_t n = strlen(text);
size_t m = strlen(pattern);
size_t count = 0;
size_t shifts = 0;
if (m == 0)
return 0;
// Create a shift table
size_t table[UCHAR_MAX + 1];
for (size_t i = 0; i &lt; UCHAR_MAX + 1; i++) {
table[i] = m;
}
for (size_t i = 0; i &lt; m - 1; i++) {
table[(unsigned char)pattern[i]] = m - 1 - i;
}
size_t i = m - 1;
while (i &lt; n) {
size_t j = 0;
while (j &lt; m &amp;&amp; text[i - j] == pattern[m - 1 - j]) {
j++;
}
shifts++;
if (j == m) {
count++;
i += m;
} else {
i += table[(unsigned char)text[i]];
}
}
printf(&quot;Boyer-Moore algorithm shifts: %zu\n&quot;, shifts);
return count;
}

答案2

得分: 0

Cast into a non-char (like an unsigned char) to get rid of the warning:

i += table[(unsigned char)text[i]];

You could also declare the lookup table to be the correct size by using CHAR_BIT.

#include <limits.h>

int table[1u << CHAR_BIT]; // 256 on most platforms
for (int i = 0; i < (1u << CHAR_BIT); i++) {

table will then be the correct size for whatever size a char has on your system.

英文:

Cast into a non-char (like an unsigned char) to get rid of the warning:

i += table[(unsigned char)text[i]];

You could also declare the lookup table to be the correct size by using CHAR_BIT.

#include &lt;limits.h&gt;

int table[1u &lt;&lt; CHAR_BIT]; // 256 on most platforms
for (int i = 0; i &lt; (1u &lt;&lt; CHAR_BIT); i++) {

table will then be the correct size for whatever size a char has on your system.

huangapple
  • 本文由 发表于 2023年3月7日 02:41:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定