Ошибка array initializer must be an initializer list

The rules of C says that you can’t initialize an array using a pointer. Instead define the array then copy to it:

char arr[strlen(val) + 1];  // Make sure there's enough space
strcpy(arr, val);

Then you can not define empty arrays. An array must have a size. And using the array newArr in the main function is wrong anyway since the function you call returns a pointer. So newArr must be a pointer as well.


Now with that out of the way, there are a couple of other things in your (current) code that are very wrong.

The first being the size of the array arr. An array of two characters can only hold space for one-character string. Remember that strings are null terminated, there must be space for the full string plus the terminator.

The second problem is that you return a pointer to a local variable. Once the function insertToArray returns, all its local variables cease to exist. Having a pointer to one of those variables will lead to undefined behavior when you use it.

The fix to the first problem is shown above. The fix to the second problem is a little harder, and involves either passing an extra argument to the function or allocating memory dynamically. I recommend the extra argument way:

char * insertToArray(const char * val, char * arr){
    strcpy(val, arr);

    // do some other staffs here to the value

    return arr;
}

Then call it like

char newArr[strlen(s1[i]) + 1];
insertToArray(s1[i], newArr);

First, when declaring a char array, you’ve to specify its size within the brackets like:

char arr[10];

except when you’re initializing it with a string literal.

And since we don’t know the number of characters the user will enter beforehand we may consider that GetString() takes care of that and returns a string (a char *). You may just declare a string and assign GetString() to it like that:

string s = GetString();

then access the contents of that string like you’d do with a char array. For example, if I wanna print out the first char in that string I may have something like this:

printf("%cn", s[0]);

Second, assuming you’re using a char array for any reason, you don’t have to cast the char you’re accessing to a char since it’s already a char! So considering this piece of code:

char arr[6] = {'h', 'e', 'l', 'l', 'o', ''};
printf("%cn", arr[0]); // no need to say (char) arr[0]

Lastly, you may print out the ciphered chars directly without storing them since we don’t need them after printing them out.

Edit: the error

array initializer must be an initializer list or string literal

means that when you declare an array, you have to initialize it using one of the following methods:

  1. char arr[6] = {'h', 'e', 'l', 'l', 'o', ''}; // initializer list
  2. char arr[6] = "hello"; // string literal

    char arr[] = "hello"; // also a string literal

A third way to initialize an array would be initializing its indices individually like that:

char arr[6];

arr[0] = 'h';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
arr[5] = '';

The rules of C says that you can’t initialize an array using a pointer. Instead define the array then copy to it:

char arr[strlen(val) + 1];  // Make sure there's enough space
strcpy(arr, val);

Then you can not define empty arrays. An array must have a size. And using the array newArr in the main function is wrong anyway since the function you call returns a pointer. So newArr must be a pointer as well.


Now with that out of the way, there are a couple of other things in your (current) code that are very wrong.

The first being the size of the array arr. An array of two characters can only hold space for one-character string. Remember that strings are null terminated, there must be space for the full string plus the terminator.

The second problem is that you return a pointer to a local variable. Once the function insertToArray returns, all its local variables cease to exist. Having a pointer to one of those variables will lead to undefined behavior when you use it.

The fix to the first problem is shown above. The fix to the second problem is a little harder, and involves either passing an extra argument to the function or allocating memory dynamically. I recommend the extra argument way:

char * insertToArray(const char * val, char * arr){
    strcpy(val, arr);

    // do some other staffs here to the value

    return arr;
}

Then call it like

char newArr[strlen(s1[i]) + 1];
insertToArray(s1[i], newArr);

First, when declaring a char array, you’ve to specify its size within the brackets like:

char arr[10];

except when you’re initializing it with a string literal.

And since we don’t know the number of characters the user will enter beforehand we may consider that GetString() takes care of that and returns a string (a char *). You may just declare a string and assign GetString() to it like that:

string s = GetString();

then access the contents of that string like you’d do with a char array. For example, if I wanna print out the first char in that string I may have something like this:

printf("%cn", s[0]);

Second, assuming you’re using a char array for any reason, you don’t have to cast the char you’re accessing to a char since it’s already a char! So considering this piece of code:

char arr[6] = {'h', 'e', 'l', 'l', 'o', ''};
printf("%cn", arr[0]); // no need to say (char) arr[0]

Lastly, you may print out the ciphered chars directly without storing them since we don’t need them after printing them out.

Edit: the error

array initializer must be an initializer list or string literal

means that when you declare an array, you have to initialize it using one of the following methods:

  1. char arr[6] = {'h', 'e', 'l', 'l', 'o', ''}; // initializer list
  2. char arr[6] = "hello"; // string literal

    char arr[] = "hello"; // also a string literal

A third way to initialize an array would be initializing its indices individually like that:

char arr[6];

arr[0] = 'h';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
arr[5] = '';

Actually, I think it’s in library/blas/AutoGemm, line 221:

    "  DATA_TYPE_STR rC[MICRO_TILE_NUM_ROWS][MICRO_TILE_NUM_COLS] = {0};" + endLine +

But changing this to:

    "  DATA_TYPE_STR rC[MICRO_TILE_NUM_ROWS][MICRO_TILE_NUM_COLS];" + endLine +

… I still get incorrect results, and some errors, eg:

[ RUN      ] testClBlas.colMajor
Using NVIDIA Corporation , OpenCL platform: NVIDIA CUDA
Using OpenCL device: GeForce 940M
initializing clblas
OpenCL error -38 on line 232 of /home/user/git/DeepCL/clMathLibraries/clBLAS/src/library/blas/xgemm.cc
OpenCL error -38 on line 232 of /home/user/git/DeepCL/clMathLibraries/clBLAS/src/library/blas/xgemm.cc
OpenCL error -38 on line 232 of /home/user/git/DeepCL/clMathLibraries/clBLAS/src/library/blas/xgemm.cc
OpenCL error -52 on line 239 of /home/user/git/DeepCL/clMathLibraries/clBLAS/src/library/blas/xgemm.cc
/home/user/git/DeepCL/test/testClBlas.cpp:215: Failure
Value of: C[0]
  Actual: 0.0320347
Expected: 0
/home/user/git/DeepCL/test/testClBlas.cpp:216: Failure
Value of: C[1]
  Actual: -0.0424018
Expected: -1
/home/user/git/DeepCL/test/testClBlas.cpp:217: Failure
Value of: C[2]
  Actual: -0.0419845
Expected: 22
clblas teardown
[  FAILED  ] testClBlas.colMajor (118 ms)

test case:

TEST(testClBlas, colMajor) {
    EasyCL *cl = EasyCL::createForFirstGpuOtherwiseCpu();

    float A[] = {1, 3,
                 2, 7,
                 9, 5};
    float B[] = {3,
                 -1};

    float C[3];
    transpose(A, 3, 2);
    transpose(B, 2, 1);
    ClBlasInstance clblasInstance;
    CLWrapper *AWrap = cl->wrap(6, A);
    CLWrapper *BWrap = cl->wrap(2, B);
    CLWrapper *CWrap = cl->wrap(3, C);
    AWrap->copyToDevice();
    BWrap->copyToDevice();
    ClBlasHelper::Gemm(
        cl,
        clblasColumnMajor,
        clblasNoTrans, clblasNoTrans,
        3, 2, 1,
        1,
        AWrap, 0,
        BWrap, 0,
        0,
        CWrap, 0
    );
    CWrap->copyToHost();
    transpose(C, 1, 3);
    EXPECT_EQ(0, C[0]);
    EXPECT_EQ(-1, C[1]);
    EXPECT_EQ(22, C[2]);

    delete CWrap;
    delete BWrap;
    delete AWrap;

    delete cl;
}

Я работаю над мелким (симпатичным) принтером для POD, STL и составных типов, таких как массивы. При этом я также возился со списками инициализации и наткнулся на следующее объявление

std::vector<double[3]> arr{ { 10, 11, 12 }, { 20, 21, 22 } };

Кажется, что и VC2013, и G ++ 4.8 не совсем счастливы и выдают непротиворечивое сообщение об ошибке, которое в любом случае не очень полезно для меня

Для VC ++: error C3074: an array can only be initialized with an initialize-list

Для G ++ 4.8: error: array must be initialized with a brace-enclosed initialize

Так что или здесь нельзя использовать списки инициализации, или мой синтаксис совершенно неверный?

Похожий синтаксис следующий синтаксис

std::vector<std::array<int, 3>>  arr{ { 10, 11, 12 }, { 20, 21, 22 } };

Какова возможная проблема с моим списком инициализации?

  • Заметка Я понимаю, что я должен использовать std::array вместо массивов типа С, но я просто экспериментирую.
  • Заметка Если вы не хотите поиграть с этим, вот IDEONE версия
  • Заметка Кроме того, было бы весьма полезно, если бы вы могли вернуть меня обратно к стандарту.

5

Решение

Чтение текущий проект стандарта C ++ 1y.

До таблицы 99:

T
является
EmplaceConstructible
в
Икс
от
арг
для нуля или более аргументов
арг
, означает, что
следующее выражение правильно сформировано:
allocator_traits :: construct (m, p, args)

Таблица 100:

X(il);              |  Equivalent to      | X(il.begin(), il.end());
--------------------+---------------------+--------------------------------
X(i, j);            |                     | Requires:
X a(i, j);          |                     | T shall be EmplaceConstructible
| into X from *i.

Так std::vector<double[3]> v{ {1,2,3}, {4,5,6} }; действует, если double[3] является EmplaceConstructible от {1,2,3} как элемент списка инициализатора, передаваемого std::vector<double[3]>,

Есть также пункт о прямых итераторах, но это не проблема (так как std::initialzier_list итераторы являются прямыми итераторами).

std::vector<T> занимает std::initializer_list<T> параметр.

Так std::initializer_list<double[3]> список кандидатов.

Первый, std::initializer_list<double[3]> x = {{1.0, 2.0, 3.0}}; не может скомпилировать в gcc. Но предположим, что это ошибка в gcc.

Во-вторых, ::new (nullptr) double[3](std::initializer_list<double>{1.0, 2.0, 3.0}); размещение нового, которое EmplaceConstructable сводится к отсутствию подходящего construct переопределить, не компилируется.

Так double[3] не является EmplaceConstruble из std::initalizer_list<double> ни из double[3] и ничего другого (поскольку ошибка возникает из-за того, что я использовал скобки, а не из-за того, что было в скобках, в месте размещения новых), если только распределитель не делает магию, о которой я не знаю, чтобы избежать размещения новых.

Таким образом, ваш код нарушает текущий черновой стандарт, и, вероятно, C ++ 11 и, конечно, C ++ 03 (который предъявляет более строгие требования к контейнерам).

5

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

Это ошибка в gcc и MSVC; Clang компилирует ваш код правильно.

Последние версии gcc на самом деле аварийно завершают работу («ice») компилятора:

внутренняя ошибка компилятора: проверка дерева: ожидаемый класс «type», имеет «исключительный» (error_mark) в useless_type_conversion_p, в tree-ssa.c: 1189

Стандарт достаточно ясен; от [Dcl.init.list]:

5 — объект типа std::initializer_list<E> построен из списка инициализатора, как если бы реализация выделяла массив N элементы типа E, где N это количество элементов в списке инициализатора. Каждый элемент этого массива инициализируется копией с соответствующим элементом списка инициализатора, и std::initializer_list<E> Объект создан для обращения к этому массиву. […]

Адаптируем пример из этого абзаца:

using E = double[3];
using X = std::vector<E>;
E __a[2] = {{10, 11, 12}, {20, 21, 22}};
X x(__a, __a+2);

Это немного обманывает, хотя; более близкий перевод напишет E __a[2] = {E{10, 11, 12}, E{20, 21, 22}};, который не действителен. Но это конечно является можно копировать-инициализировать массив double[3] из списка фигурных скобок: E __a0 = {10, 11, 12};

3

Я новичок в C. Я не знаю, почему возникает эта ошибка и как ее исправить?

void FPS_PRINT_ENROLLED(){
  int checkNum = 0;
  int ID = 0;
  int num_Enroll = 0;
  num_Enroll = Available_ID();
  char strNum[3] = 0;
  itoa(num_Enroll, strNum);
  uint32_t numLen = strlen((char *)strNum);
  UART_send_A3("Number of Stored Prints: ", 25);
  UART_send_A3(&strNum, numLen);
  }

Сообщение об ошибке: array initializer must be an initializer list or string literal

См. Прикрепленный снимок экрана с сообщением об ошибке. Также прикреплен файл c.

Screenshot of error message

Кстати, это в PSoC Creator 4.1, который использует язык C.

ссылка для скачивания файла кода через GoogleDrive

1 ответ

Лучший ответ

char strNum[3] = 0;

Эта строка создает трехсимвольную строку. Затем вы используете его как строку с функцией strlen и uart_send.

Как строка C, она должна заканчиваться нулевым символом, поэтому у вас есть только два используемых символа. Он также должен быть инициализирован как строка, компилятор сообщает вам, что вы сделали это неправильно.

Попробуйте что-нибудь вроде одной из этих строк

char strNum[3] = ""; // Empty string
char strNum[3] = "AB"; // Full string
char strNum[3] = "0"; // String holding the character zero


0

lod
14 Ноя 2018 в 06:32

So here is my question. I am tring to run a program I found online and it is failing to compile. Why am I getting an error: "array initializer must be an initializer list or string literal" when I am in fact using a string? I know this code works for others running windows, but not for me on the m1 Mac.

I am trying to initialize a string array using

string f[3] = " ";

#include <iostream>
#include <cstdio>
#include <string.h>
#include <unistd.h>
#include <cstdlib>

using namespace std;

int main()
{
    bool cont = true;
        
    char buffer[100] = {};

    while (cont)
    {
        cout << "nnEnter a command: ";
        
        cin.get (buffer, 90);
    
        //REMOVE
        if (strstr (buffer,"remove") != NULL)
        {
            char* t = strchr (buffer,' ');

            if(t != NULL)
            {
                if(remove( t+1 ) != 0)
                    cout << "nnError deleting the file.";
                else
                    cout << "nnThe file has successfully been deleted.";
            }
    
            else
                cout << "nnInvalid command. Filename not entered.";

        }

        //EXIT
        else if (strstr (buffer,"exit") != NULL)
            cont = false;
        

        //RENAME
        else if (strstr (buffer,"rename") != NULL)
        {
            char* t = strchr (buffer,' ');
            
            if (t != NULL)
            {
                char* oldName = t + 1;  
                    char* newName = strchr (oldName, ' ');


                if (newName != NULL)
                {
                    char temp[30] = {};
                    
                    int i = 0;
                    for(char* start = oldName; start != newName; start++)
                    {
                        temp[i] = *start;
                        i++;
                    }

                    newName++;
                

                    if(rename( temp , newName ) != 0)
                        cout << "nError renaming the file.";
                        else
                        cout << "nThe file has successfully been renamed.";
                }   
                    
                else
                    cout << "nnNew Name of the file not entered.";
            }
            
            else
                cout << "nnInvalid command.";

        }


        //RMDIR
        else if (strstr (buffer,"rmdir") != NULL)
        {
            char* t = strchr (buffer,' ');

            if(t != NULL)
            {
                if(rmdir( t+1 ) != 0)
                    cout << "nnError deleting the directory.";
                else
                    cout << "nnThe directory has successfully been removed.";
            }
    
            else
                cout << "nnInvalid command. DirectoryName not entered.";

        }
        

        //ECHO
        else if (strstr (buffer,"echo") != NULL)
        {
            char* t = strchr (buffer,'"');

            if (t != NULL)
            {
                char* data = t + 1; 

                //Extracting the data
                char temp[200] = {};
                
                int i = 0;

                for(; data[i] != '"'; i++)
                {
                    temp[i] = data[i];
                }


                //Checking if filename is given or not
                    char* fileN = strchr (data + i, ' ') ;

                if (fileN != NULL)
                {
                    fileN++;
                
                    // create a FILE typed pointer
                    FILE *file_pointer; 
    
                    // open the file for writing
                    file_pointer = fopen (fileN, "w");
                    
                    if (file_pointer != NULL)
                    {
                        // Write to the file
                        fprintf (file_pointer,"%s", temp);
    
                        // Close the file
                        fclose (file_pointer); 
                    
                        cout << "nnThe file has been successfully created.";
                    }
                    
                    else
                        cout << "nnCould not create the file.";
                }   
                    
                //If filename isn't given then simply print the data on console
                else
                {
                    cout << endl << endl << temp;
                }
            }
    
            else
                cout << "nnInvalid command. Data not given";
        }

        //UNZIP
        else if (strstr (buffer,"unzip") != NULL)
        {
            char* t = strchr (buffer,' ');

            if(t != NULL)
            {
                char temp[50] = "tar xvf";
    
                if( system( strcat(temp,t) ) != 0 )
                    cout << "nnError unzipping the file.";
                else
                    cout << "nnThe file has been successfully unzipped.";
            }
    
            else
                cout << "nnInvalid command. FileName not entered.";   
        }

        
        //ZIP
        else if (strstr (buffer,"zip") != NULL)
        {
            char* t = strchr (buffer,' ');

            if(t != NULL)
            {
                char temp[50] = "tar cvf";

                if( system( strcat( temp,t) ) != 0 )
                    cout << "nnError zipping the file.";
                else
                    cout << "nnThe file has been successfully zipped.";
            }
    
            else
                cout << "nnInvalid command."; 
        }

        
        else if (strstr (buffer,"out") != NULL)
        {
            int i = 1;
    
            //Checking '-l'
            bool lineByLine = false;
            char* lpos = strstr (buffer,"-l");              
            
            if (lpos != NULL)
            {   
                lineByLine = true;
                i++;
            }
    
            string s(buffer);
            string fileN = "";              
                    
            string delimiter = " "; 
            size_t pos = 0;
        
            while ( i > 0 )
            {   
                pos = s.find(delimiter);
                s.erase(0, pos + delimiter.length());
                i--;
            }
            

            //Now extracting the file names
            string f[3] = " ";
            
            i = 0;

            while ( (pos = s.find(delimiter)) != -1)
            {
                f[i] = s.substr(0, pos);
                    s.erase(0, pos + delimiter.length());
                i++;
            }

            //if atleast one filename is present
                
            if ( s != "out" && s != "-l" && s != "" )
            {
                f[i] = s;
        
                //Opening the files and printing the contents
    
                int c;
                FILE *file;
                
                int j = 0;
    
                bool delay = false;
                char x;         

                while ( j <= i)
                {               
                    char fName[50];
                    strcpy(fName, f[j].c_str());

                    //Printing the contents of the file(s)

                    file = fopen(fName, "r");
                    char line[256];
                    
                    cout << "nnThe contents of the file " << fName << " are as follows : nn";

                    if (file)
                    {
                        if (lineByLine)
                        {   
                            while (fgets(line, sizeof(line), file)) 
                            {
                                        printf("%s", line);
                                
                                //Delay loop
                                delay = true;
                
                                while(delay)
                                {   
                                    cout << "nnPress some key to print the next linenn";
                                    getchar();
                                    delay = false;  
                                }                        
                                }

                        }
                
                        else
                        {
                                while ((c = getc(file)) != EOF)
                                putchar(c);
                        }

                        
                            fclose(file);
                    }
    
                    else
                        cout << "nnCould not open the file " << fName << " .";
    
                    j++;
    
                    //Delay loop
                    delay = true;
                
                    while(delay)
                    {   
                        cout << "nnPress some key to continuenn";
                        getchar();
                        delay = false;  
                    }
                }
            }
            
            else
                cout << "nnNo filename entered.nn";         
        }

        else
            cout << "nnInvalid Command. Kindly enter a valid command.";


        cin.ignore();
    }



    cout << "nnnExiting the CLI.nn";
    
    return 0;
}

>Solution :

If you are trying to create a string of length 3, you should do this:

string f(3, ' ');

If you are trying to create an array of 3 different strings, then the issue with your code is that you have a type mismatch – you are trying to assign a single string to an array of strings. Instead, you would want to do this:

string f[3] = {" ", " ", " "};

Looking at your code, it looks like you want to create an array of strings. However, it also looks like you could be reading in any number of strings (unless there is some logic in your code where you are confident it will always be 3?) so I recommend using a std::vector.

 std::vector<std::string> f;

Which you can add strings to with the push_back() method like this:

f.push_back(s.substr(0, pos));


Go to cs50


r/cs50


r/cs50

Demanding, but definitely doable. Social, but educational. A focused topic, but broadly applicable skills. CS50 is the quintessential Harvard (and Yale!) course.




Members





Online



by

Tjonge



Pset6 «array initializer must be an initializer list»

I am trying to initialize a hash table. But I am getting this message: array initializer must be an initializer list. What does this mean? Thanks in advance.

  • Ошибка arma 3 0xc0000005
  • Ошибка ark survival evolved the ue4 shootergame has crashed and will close
  • Ошибка arithmetic overflow error converting expression to data type int
  • Ошибка arithmetic overflow error converting expression to data type datetime
  • Ошибка archpr выбранный файл не является zip rar ace arj архивом