Initializer string for array of chars is too long ошибка

Ошибка "initializer-string for array of chars is too long" C++ Решение и ответ на вопрос 2727728
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
using namespace std;
 
const int n = 5;
 
typedef struct
{
    int day;
    int month;
    int year;
}
DATE;
 
typedef struct
{
    char naimenuv[20];
    int cina;
    DATE datavir;
    int termin;
    int kilkist;
    char virobnyk[20];
}shop;
 
bool repair(shop *pShop)    //проверка на просроченность
{
    time_t seconds;
    struct tm currdate = { 0 };
 
    seconds = time(NULL);   //время в секундах с 1.1.1970 года
 
    //сформируем структуру currdate с датой изготовления товара. Остальные поля = 0 (0 год соответствует 1900, месяц - с 0)
    currdate.tm_year = pShop->datavir.year-1900; currdate.tm_mon = pShop->datavir.month-1;  currdate.tm_mday = pShop->datavir.day;
 
    //проверим время (в секундах): разность текущей и даты товара со сроком годности
    return (seconds - mktime(&currdate) > pShop->termin * 24 * 60 * 60); //true - товар просрочен
}
 
int main () {
    setlocale(0, "rus");
 
    shop tovar[n] = { "Сосиски", 50, {20,10,2020}, 15, 130, "Завод Петровский",
                "Хлеб", 14, {19,10,2020}, 5, 150, "Хлебозавод",
                "Вафли", 25, {19,10,2020}, 30, 98, "Вафлезавод",
                "Растишка", 40, {21,10,2020}, 45, 73, "Молокозавод",
                "Баунти", 35, {20,10,2020}, 35, 31, "Завод кондитерский" };
 
    cout << "***** Список товаров, срок годности которых менее 20-ти дней:" << endl;
    
    for (int i = 0; i < n; ++i)
    {
        if (tovar[i].termin < 20)
        {
            cout << tovar[i].naimenuv << " " << tovar[i].termin << endl;
        }
    }
    
    cout << endl << "***** Просроченные товары:" << endl;
    
    int     count = 0;
    for (int i = 0; i < n; ++i)
    {
        if (repair(&tovar[i]))
        {
            count++;
            cout << tovar[i].naimenuv << " " << tovar[i].datavir.day << "." << tovar[i].datavir.month << " " << tovar[i].termin << endl;
        }
    }
    cout << "Всего: " << count << endl;

Следующая программа прекрасно компилируется в C с предупреждениями, но не компилируется в C ++. Зачем? Какова причина?

#include <stdio.h>
int main(void)
{
char a[5]="Hello";
a[0]='y';
puts(a);
for(int i=0;i<5;i++)
printf("%c",a[i]);
return 0;
}

Предупреждение:

Warning:[Error] initializer-string for array of chars is too long [-fpermissive] enabled by default

Но если программа скомпилирована как программа C ++, то компилятор C ++ выдает следующую ошибку:

[Error] initializer-string for array of chars is too long [-fpermissive]

Я использую компилятор GCC 4.8.1.

5

Решение

Краткий ответ: потому что C и C ++ — это разные языки с разными правилами.

Длинный ответ: в обоих случаях причина в том, что массив слишком мал для строкового литерала. Литерал состоит из пяти видимых символов с нулевым терминатором на конце, поэтому общий размер равен 6.

В C вы можете инициализировать массив слишком длинной строкой; лишние символы просто игнорируются:

C99 6.7.8 / 14: Массив символьного типа может быть инициализирован литералом символьной строки, необязательно заключенным в фигурные скобки. Последовательные символы литерала символьной строки (включая завершающий нулевой символ, если есть место или если массив имеет неизвестный размер) инициализируют элементы массива.

Компилятор предупреждает, что строка слишком велика, поскольку почти наверняка указывает на ошибку; но он не может отклонить код, если вы не скажете, чтобы он воспринимал предупреждения как ошибки.

В C ++ инициализатору не разрешено быть больше, чем массив:

C ++ 11 8.5.2 / 2: Инициализаторов не должно быть больше, чем элементов массива.

поэтому для этого языка компилятор должен выдать ошибку.

В обоих языках, когда вы хотите, чтобы символьный массив соответствовал размеру инициализатора строкового литерала, вы можете не указывать размер, и компилятор сделает все правильно.

char a[] = "hello";  // size deduced to be 6

22

Другие решения

Проблема в нижней строке

char a[5]="Hello";

Нет места для хранения завершающего нуля.

По умолчанию, gcc не выдает никаких ошибок для этого случая с -fpermissive опция включена. Так что компилирует нормально в C,

Согласно требованию от языковых стандартов,

  • ЗаC99 стандарт, глава 6.7.9, пункт 14,

Массив символьного типа может быть инициализирован символьным строковым литералом или строковым литералом UTF-8, необязательно заключенным в фигурные скобки. Последовательные байты строкового литерала (включая завершающий нулевой символ, если есть место или массив имеет неизвестный размер) инициализируют элементы массива.

  • За C++11, глава 8.5.2, пункт 2

Инициализаторов не должно быть больше, чем элементов массива.

Итак, код компилируется (с предупреждениями) с gcc, выдает ошибку с g++,

10

Допустимая строка в C и C ++ должна иметь терминатор и в

char a[5]="Hello";

Там нет места для нулевого терминатора и не является допустимой строкой.

Так что это может не быть ошибкой в ​​C, но вы обязательно столкнетесь с проблемами при использовании встроенных строковых функций, таких как strlen() и семья.

5

Потому что «Привет» 6 charс долго и г ++ без -fpermissive не будет инициализировать 5 char массив с ним, но GCC будет.

3

  • Forum
  • Beginners
  • Initializer string is too long

Initializer string is too long

Whenever I attempt to compile this code I get the error «initializer-string for array of chars is too long». Any help is greatly appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <windows.h>

using namespace std;

char Map[10][10] = {"##########",
                    "#        #",
                    "#        #",
                    "#        #",
                    "#        #",
                    "#        #",
                    "#        #",
                    "#        #",
                    "#@       #",
                    "##########" };

int Gamespeed = 100;
int Level = 0;
bool stopgame = false;

int main()
{
    
    while(stopgame == false)
    {
                   
        for (int y = 0; y < 10; y++) 
        {
            cout << Map[y] << endl;
        }
        for (int y = 0; y < 10; y++)
        {
            for (int x = 0; x < 10; x++)
            {
                switch (Map[y][x])
                {
                       case '@':
                       {
                            if (GetAsyncKeyState(VK_UP) != 0)
                            {
                               int y2 = y-1;
                               
                               switch(Map[y2][x])
                               {
                                   case ' ':
                                   {
                                        Map[y][x] = ' ';
                                        y -= 1;
                                        Map[y2][x] = '@';
                                   }
                               }
                            }
                       }
                }
            }
        }
    }
    
}

Each string literal has additional character — terminating zero. So your array shall be declared as

char Map[10][11];

because it is initialized by string literal «##########» that has in total 11 characters (including the terminating zero).

Last edited on

"##########" doesn’t contain 10 characters. It contains 11.

There’s a hidden

»

character added to the end, so it actually looks like this:
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', ''}

»

is called the NUL character, and it’s used as a hint where the array ends.

Thank you for the help vlad and Catfish

Last edited on

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:
  • Initialize system error handler
  • Initialize player error utorrent
  • Initialize order server failed error 2147417851 elsa
  • Initialize failed ssdevm dll как исправить
  • Initialization sequence completed with errors как исправить