首先在此定义的多个定义只有一个文件

时间:2018-02-11 01:54:37

标签: c

我是c的新手,当我用-g编译代码时遇到错误。 当我用-o编译我的代码时,它编译但崩溃。 当我用-g编译时,这些是错误消息:

/afs/pitt.edu/home/j/t/jth64/private/cs449/proj1test/bmp_edit.c:42: multiple 
definition of `invert'
proj1test:(.text+0xe4): first defined here
/tmp/ccA3Apso.o: In function `main':
/afs/pitt.edu/home/j/t/jth64/private/cs449/proj1test/bmp_edit.c:110: 
 multiple definition of `main'
proj1test:(.text+0x4b7): first defined here

还有更多文字,但我很确定这两个是唯一的问题。在我发布这个问题之前,我读了很多关于这一点,但似乎所有其他链接器错误是因为多个文件,而我得到它们而我只有一个文件。

这是我目前的文件:

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

struct headBMP {
    char formatIdentifier[2];
    int fileSize;
    short resVal1;
    short resVal2;
    int offSet;
};

struct headDIB {
    int headerSize;
    int width;
    int height;
    short planes;
    short bitsPerPixel;
    int compressionScheme;
    int imageSize;
    int horizontalRes;
    int verticalRes;
    int palette;
    int importantColors;
};

struct headRGB {
    unsigned char red;
    unsigned char blue;
    unsigned char green;
};

void invert (char file[])
{
    struct headBMP bmp;
    struct headDIB dib;
    struct headRGB rgb;
    FILE *fp;
    fp = fopen (file, "rb+");
    /*--------BMP--------*/
    fread (bmp.formatIdentifier, 1, 2, fp);
    if (bmp.formatIdentifier[0] != 'B' || bmp.formatIdentifier[1] != 'M') {
        printf ("We do not support this type of file! \n");
        exit (-1);
    }
    fread (&bmp.fileSize, 4, 1, fp);
    fread (&bmp.resVal1, 2, 1, fp);
    fread (&bmp.resVal2, 2, 1, fp);
    fread (&bmp.offSet, 4, 1, fp);

    /*--------DIB--------*/
    fread (&dib.headerSize, 4, 1, fp);
    if (dib.headerSize != 40) {
        printf ("We do not support this type of file! \n");
        exit (-1);
    }
    fread (&dib.width, 4, 1, fp);
    fread (&dib.height, 4, 1, fp);
    fread (&dib.planes, 2, 1, fp);
    fread (&dib.bitsPerPixel, 2, 1, fp);
    fread (&dib.compressionScheme, 4, 1, fp);
    fread (&dib.imageSize, 4, 1, fp);
    fread (&dib.horizontalRes, 4, 1, fp);
    fread (&dib.verticalRes, 4, 1, fp);
    fread (&dib.palette, 4, 1, fp);
    fread (&dib.importantColors, 4, 1, fp);
    /*fseek(fp, 10, SEEK_SET);*/

    /*--------RGB--------*/
    int i = 0;
    while (i < dib.width) {
        int j = 0;
        while (j < dib.height) {
            fread (&rgb.red, 1, 1, fp);
            unsigned int r = rgb.red;
            r = ~r;
            rgb.red = (char) r;

            fread (&rgb.green, 1, 1, fp);
            unsigned int g = rgb.green;
            g = ~g;
            rgb.green = (char) g;

            fread (&rgb.blue, 1, 1, fp);
            unsigned int b = rgb.blue;
            b = ~b;
            rgb.blue = (char) b;

            fseek (fp, -3, SEEK_CUR);
            fwrite (&rgb.red, 1, 1, fp);
            fwrite (&rgb.green, 1, 1, fp);
            fwrite (&rgb.blue, 1, 1, fp);
            j++;
        }
        i++;
    }
    fclose (fp);
}

int main (int argc, char *argv[])
{
    if (strncmp (argv[1], "-invert", 7) == 0) {
        invert (argv[1]);
    }
    return 0;
}

这一直困扰着我,所以我感谢任何帮助。欢呼声。

1 个答案:

答案 0 :(得分:2)

您的代码很好,您刚刚搞砸了argv[X]中的main()索引。你需要的是:

int main (int argc, char *argv[])
{
    if (argc < 3) {
        fprintf (stderr, "error: insufficient input.\n"
                        "usage: %s [-invert] <filename.bmp>\n", argv[0]);
        return 0;
    }

    if (strncmp (argv[1], "-invert", 7) == 0) {
        invert (argv[2]);
    }
    return 0;
}

注意 invert (argv[1])更改为invert (argv[2]) ...

我还会从上面的列表中重新复制您的代码,以确保您没有任何导致问题的流浪非ASCII字符。请记住,代码必须是纯文本。您无法在任何将在源文件中存储二进制格式字符的编辑器中对其进行编辑。您还需要检查以确保不包含BOM(字节顺序标记)作为文件的前三个字符(尽管某些编译器会忽略它)。

检查代码中是否有其他字符的最简单方法是使用hexdump -Cv yourfile(在Linux上)或在windoze上以WinHex(或等效文件)打开文件。您可能还希望通过dos2unixunix2dos(根据需要)运行代码,以确保行结尾等不会导致您出现问题。

<强>编译:

添加argc检查并修复索引后,您的代码会在没有警告的情况下编译:

$ gcc -Wall -Wextra -pedantic -Wshadow -std=gnu11 -Ofast -o bin/bmp_edit bmp_edit.c

(是的,它确实反转了位图)

enter image description here

然后运行你的代码:

./bin/bmp_edit -invert ~/tmp/tt/testbmp_black.bmp

结果.bmp

enter image description here

更新每条评论,重新验证

在查看如何完全验证fopenfreadfwrite之前,请先注意一下C风格。虽然不是错误,但C的标准编码样式避免使用camelCaseMixedCase变量名来支持所有小写,同时保留大写用于宏和常量的名称。这是一个风格问题 - 所以它完全取决于你,但如果不遵循它可能会在某些圈子中产生错误的第一印象。参见例如NASA - C Style Guide, 1994

现在进行验证。 C不能保护你不要做一些愚蠢的事情。它完全按照你的要求去做,它没有训练轮。这意味着如果您对不存在的文件调用fopen,然后在调用FILE*等时开始使用fread指针,则C不会发出错误({ {1}})对您而言 - 由您自己加入代码。

验证规则很简单。如果您打开它,请验证它是否已打开。如果您从中读取,请验证您是否阅读了您的意图。如果您写信给它,请验证您写下您认为自己写的内容。如果在写入后关闭它,请确认关闭时没有错误。如果你分配它,验证分配成功等等......你得到漂移。 验证,验证,验证!!

重新编写代码并进行充分验证,以确定发生故障的位置 - 在打开,读取或写入过程中的任何时刻都不困难(虽然有点单调乏味)。只需遵守规则:

"File Not Found"

仔细检查并确保您了解验证。如果你不这样做,那就问问。