【问题标题】:"Parse error before "]" token" when assigning to variable[]分配给变量[]时“在“]”标记之前解析错误
【发布时间】:2015-04-21 17:13:03
【问题描述】:

我的 C 程序如下。它试图从文件中读取一组值,并创建一个表格来生成一些浮点数的平均值。

int main(void)
{

    int lake, beach, samples, count, sum;
    float e_coli, ave;
    char recc[20], lakename[20], beachname[20];
    FILE *in;
    sum = 0;
    count = 0;
    in = fopen("july15.data", "r");
    printf("Lake   |   Beach   | Avg E Coli Level |  Reccomendation |\n");
    while (1)
    {
        fscanf(in, "%d, %d, %d", &lake, &beach, &samples);
        count = samples;
        while (count < samples)
        {
            fscanf(in, "%f", e_coli);
            sum = sum + samples;
        }
        ave = sum / samples;
        if (lake == 1)
            lakename[] = "Ontario";
        else if (lake == 2)
            lakename[] = "Erie";
        else if (lake == 3)
            lakename[] = "Huron";
        else if (lake == 4)
            lakename[] = "Muskoka";
        else if (lake == 5)
            lakename[] = "Simcoe";
        if (beach == 100)
            beachname[] = "Kew Beach";
        else if (beach == 101)
            beachname[] = "Sunnyside Beach";
        else if (beach == 102)
            beachname[] = "Sandbanks";
        else if (beach == 201)
            beachname[] = "Port Dover";
        else if (beach == 202)
            beachname[] = "Port Burwell";
        else if (beach == 203)
            beachname[] = "Crystal Beach";
        else if (beach == 301)
            beachname[] = "Goderich";
        else if (beach == 302)
            beachname[] = "Sauble Beach";
        else if (beach == 303)
            beachname[] = "Kincardine";
        else if (beach == 401)
            beachname[] = "Muskoka Beach";
        else if (beach == 501)
            beachname[] = "Sibbald Point";
        if (samples < 3)
            recc[] = "INSUFFICENT DATA";
        else if (samples > 3 && ave < 50)
            recc[] = "OPEN";
        else if (samples > 3 && ave > 50)
            recc[] = "CLOSED";
        printf("%s,      %s,      %f,      %s\n", lakename, beachname, ave, recc);
    }
    return(0);
}

不幸的是,它在第​​ 22、32 和 54 行产生了错误 parse error before "]" token。实际上,这些是定义字符串的第一个区域。所以第22行是lakename[] = "Ontario"第32行是beachname[] = "Kew Beach",第54行是recc[] = "INSUFFICIENT DATA"

我尝试将空格数插入[](即lakename[9] = "Ontario"),但随后出现错误"assignment makes integer from pointer without cast"

【问题讨论】:

标签: c arrays string loops while-loop


【解决方案1】:

数组在 C 中是不可赋值的。

有效的赋值/初始化是

char lakename[] = "Ontario";

你得到错误

lakename[9] = "Ontario"

因为lakename[9] 只能容纳一个字符。

无论如何,还有其他选项可以复制 strcpy() 和家庭等字符串

【讨论】:

  • char lakename[] = "Ontario"; 被恰当地称为“initialisation”。
【解决方案2】:

lakename[] = "Ontario";beachname[] = "Kew Beach"; 形式的语句是无效的 C。为了安全起见,请改用 strcncpy(beachname, "Kew Beach", sizeof(beachname)-1); 之类的东西,在上面的某个地方使用 beachname[sizeof(beachname)-1] = 0;。或者,将变量设为char *,然后将它们分配为指针。在这种情况下,这更合适。

【讨论】:

    【解决方案3】:

    假设您的输入数据看起来像下面的示例,该解决方案应该可以工作。

    1 101 5 5.2 10.9 20.1 30.56 80.6
    1 301 4 50.0 30.3 40.2 20.4
    

    代码解决方案。

    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void){
        int lake, beach, samples;
        char recc[20], lakename[20], beachname[20];
    
        FILE *in;
        in = fopen ("july15.data", "r");
        if(in == NULL) {
            exit(EXIT_FAILURE); 
        }
    
        char *line = NULL;
        size_t len = 0;
        ssize_t read;
        
        printf ("Lake   |   Beach   | Avg E Coli Level |  Reccomendation |\n");
    
        while ((read = getline(&line, &len, in)) != -1) {
            // Count number of spaces
            double sum = 0;
            int tokens = 0;
            int i = 0;
            for (; i < len; i++) {
                if (line[i] == ' ') {
                    tokens++;
                }
            }
            // Add one extra token
            tokens = tokens + 1;
            if (tokens < 4) {
                continue;
            }
    
            i = 0;
            // Convert tokens to floats
            double *values = malloc(sizeof(double) * tokens);
            char *token = strtok(line, " ");  
            while (token != NULL) {
                values[i++] = atof(token);
                token = strtok(NULL, " ");
            }
    
            lake = values[0];
            beach = values[1];
            samples = values[2];
            for (i = 3; i < tokens; i++) {
                sum = sum + values[i];
            }
            free(values);
    
            double ave = sum / samples;
            
            if (lake == 1)
                strcpy(lakename, "Ontario");
            else if (lake == 2)
                strcpy(lakename, "Erie");
            else if (lake == 3)
                strcpy(lakename, "Huron");
            else if (lake == 4)
                strcpy(lakename, "Muskoka");
            else if (lake == 5)
                strcpy(lakename, "Simcoe");
    
            if (beach == 100)
                strcpy(beachname, "Kew Beach");
            else if (beach == 101)
                strcpy(beachname, "Sunnyside Beach");
            else if (beach == 102)
                strcpy(beachname, "Sandbanks");
            else if (beach == 201)
                strcpy(beachname, "Port Dover");
            else if (beach == 202)
                strcpy(beachname, "Port Burwell");
            else if (beach == 203)
                strcpy(beachname, "Crystal Beach");
            else if (beach == 301)
                strcpy(beachname, "Goderich");
            else if (beach == 302)
                strcpy(beachname, "Sauble Beach");
            else if (beach == 303)
                strcpy(beachname, "Kincardine");
            else if (beach == 401)
                strcpy(beachname, "Muskoka Beach");
            else if (beach == 501)
                strcpy(beachname, "Sibbald Point");
            
            if (samples < 3)
                strcpy(recc, "INSUFFICENT DATA");
            else if (samples > 3 && ave < 50)
                strcpy(recc, "OPEN");
            else if (samples > 3 && ave > 50)
                strcpy(recc, "CLOSED");
    
            printf("%s,      %s,      %f,      %s\n", lakename, beachname, ave, recc);
        }
    
        free(line);
        fclose(in);
    
        return(0);
    }
    

    【讨论】:

    • sizeof 的用法没有任何意义。
    • 这仍然没有意义,因为strncpy() 的第三个参数应该用于保护,而不是溢出目标缓冲区,就像这样(假设dstchar 和不仅仅是一个指针)memset(dst, 0, sizeof dst); strncpy(dst, src, sizeof dst -1);供您参考:man7.org/linux/man-pages/man3/strncpy.3.html
    • 嘿,你说得对。我应该更加注意这一点。我将 strncpy 更改为 strcpy 并假设缓冲区始终可以适合复制的字符串。再次感谢!
    • 好的,谢谢大家。但输入数据看起来不像那样。相反,它在一行中。这是第一行:4 401 4 30.3 50.4 50.5 60.6 其中 4 是湖,401 是海滩,4 是样本数,其余 4 个浮点数是生态读数...
    • 它看起来怎么样?
    【解决方案4】:

    我会进行一些修改,使代码更具可读性,并提醒用户如果不支持没有湖泊或没有海滩

    #include <stdio.h>
    
    int main (void){
        int lake, beach, samples, count, sum;
        float e_coli, ave;
        char *recc;
        char *lakename;
        char *beachname;
        FILE *in;
    
        sum = 0;
        count = 0;
        in = fopen ("july15.data", "r");
        printf ("Lake   |   Beach   | Avg E Coli Level |  Reccomendation |\n");
    
        int iterator;
        char lake_names[6][10]={
            {"Ontario"},
            {"Erie"},
            {"Huron"},
            {"Muskoka"},
            {"Simcoe"},
            {"No lake"},
        };
    
        int beach_code[12] ={100,101,102,201,202,203,301,302,303,401,501,0};
    
        char beach_names[12][20]={
            {"Kew Beach"},
            {"Sunnyside Beach"},
            {"Sandbanks"},
            {"Port Dover"},
            {"Port Burwell"},
            {"Crystal Beach"},
            {"Goderich"},
            {"Sauble Beach"},
            {"ncardine"},
            {"Muskoka Beach"},
            {"Sibbald Point"},
            {"No beach"},
        };
    
        char reccs[3][20]={
            {"INSUFFICENT DATA"},
            {"OPEN"},
            {"CLOSED"},
        };
    
    
    
    
        while (fscanf (in, "%d, %d, %d", &lake, &beach, &samples) !=  EOF)
        {
            recc=&reccs[0][0];
            lakename=&lake_names[5][0];
            beachname=&beach_names[11][0];
    
            count = samples;
    
            while (count < samples)
            {
                fscanf (in, "%f",&e_coli);
                sum = sum + samples;
            }
    
            ave = sum / samples;
    
            for(iterator=1;iterator<5;iterator++)
            {
                if(lake==iterator)
                    lakename=&lake_names[iterator][0];
            }
    
            for(iterator=0;iterator<11;iterator++)
            {
                if(beach==beach_code[iterator])
                    beachname=&beach_names[iterator][0];
            }
    
            if (samples < 3)
                recc = &reccs[0][0];
            else if (samples > 3 && ave < 50)
                recc = &reccs[1][0];
            else if (samples > 3 && ave > 50)
                recc = &reccs[2][0];
            printf("%s,      %s,      %f,      %s\n", lakename, beachname, ave, recc);
        }
        return(0);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多