调用unsigned char[ ]
函数后,我的程序似乎没有更新main
中的changecontents
,因为它为storage[13]
输出的值与之前的值相同电话。但是,这不是我的全部代码-我将常规功能复制到了这里。
更新:对不起,我忘了指出data1 [13]已初始化-索引0到至少200包含值。
Update2:添加了readfile函数,用于初始化main中的data1。
Update3:检查了readfile中的fopen()函数是否返回了NULL
; file.gif存在。
#include <stdio.h>
int main()
{
unsigned char data1[4000] = {0};
readfile(data1, 4000, "file.gif"); // filled 3022 indices in data1; file.gif exists
printcontents(data1); // prints the array contents as desired here
changecolor(data1); // doesn’t change the array contents
printcontents(data1); // prints the same array contents as original
return 0;
}
int printcontents(unsigned char storage[ ])
{
printf(“%X”, storage[13]); // data1 passed in function call in main
return 0;
}
int changecolor (unsigned char storage[ ])
{
storage[13] = storage[13] >> 2; // data1 passed in function call in main
return 0;
}
int readfile(unsigned char storage[ ], int capacity, char filename[ ])
{
FILE * content = fopen(filename, "r");
if (content != NULL)
{
size_t numElements, bytesPer = sizeof(unsigned char);
fseek(content, 0, SEEK_END);
numElements = ftell(content);
rewind(content);
fread(storage, bytesPer, numElements, content); // returned 3022
fclose(content);
}
return 0;
}
答案 0 :(得分:2)
更新后的代码未使用capacity
中的readfile()
。该函数无法打开文件时未明确报告错误-这花了我一些时间。
这是您代码的一种变体,可产生我期望的输出:
#include <stdio.h>
int printcontents(unsigned char storage[ ]);
int changecolor (unsigned char storage[ ]);
int readfile(unsigned char storage[ ], size_t capacity, char filename[ ]);
int main(void)
{
unsigned char data1[4000] = {0};
readfile(data1, 4000, "file.gif"); // filled 3022 indices in data1; file.gif exists
printcontents(data1); // prints the array contents as desired here
changecolor(data1); // doesn’t change the array contents
printcontents(data1); // prints the same array contents as original
return 0;
}
int printcontents(unsigned char storage[ ])
{
printf("%#X\n", storage[13]); // data1 passed in function call in main
return 0;
}
int changecolor (unsigned char storage[ ])
{
storage[13] = storage[13] >> 2; // data1 passed in function call in main
return 0;
}
int readfile(unsigned char storage[ ], size_t capacity, char filename[ ])
{
FILE * content = fopen(filename, "r");
if (content != NULL)
{
size_t numElements, bytesPer = sizeof(unsigned char);
fseek(content, 0, SEEK_END);
numElements = ftell(content);
if (numElements > capacity)
numElements = capacity;
rewind(content);
if (fread(storage, bytesPer, numElements, content) != numElements)
printf("Bogus input\n"); // returned 3022
printf("Got %zu bytes\n", numElements);
for (int i = 0; i < 16; i++)
printf(" 0x%.2X", storage[i]);
putchar('\n');
fclose(content);
}
else
fprintf(stderr, "failed to open file '%s'\n", filename);
return 0;
}
我使用了随机数生成器来创建file.gif
文件。当我在该文件上运行程序时,我得到了:
Got 3023 bytes
0x62 0x66 0x74 0x77 0x76 0x62 0x66 0x6E 0x6D 0x72 0x70 0x62 0x63 0x66 0x71 0x7A
0X66
0X19
如您所见,数组位置13(0x63和0x71之间)的值从0x66(102)变为0x19(25),这是正确的“除以4”值。
不可能从这里猜测您的版本出了什么问题。最简单的猜测是文件file.gif
不存在,尽管您的说法与此相反。您的代码未显示fread()
成功。
我所做的大多数更改都是使代码通过默认的编译器警告所必需的。我正在Mojave 10.14.1上的XCode 10.1中使用clang
,并使用以下命令将arr41.c
编译为arr41
:
/usr/bin/clang -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
-Wstrict-prototypes arr41.c -o arr41
我还添加了诊断代码,以在文件未打开时发出警告,并打印读取的数据量,该数据的前16个字节,并整理打印值的格式(以换行符结尾的输出) ,通常)。
我顺便指出,这不是MCVE(Minimal, Complete, Verifiable Example)。 MCVE可能是:
#include <stdio.h>
static void printcontents(unsigned char storage[]);
static void changecolor(unsigned char storage[]);
int main(void)
{
unsigned char data1[20] = "ABCDEFGHIJKLMNOPQRS";
printcontents(data1);
changecolor(data1);
printcontents(data1);
return 0;
}
static void printcontents(unsigned char storage[])
{
printf("%#X\n", storage[13]);
}
static void changecolor(unsigned char storage[])
{
storage[13] = storage[13] >> 2;
}
输出:
0X4E
0X13
同样,这显然是正确的。
答案 1 :(得分:2)
您的问题是验证之一,通常是新程序员的事后思考,但实际上,这应该是您的编码方法的主要重点。您显示的代码(以及在您更新和替换 [1] 问题中的原始代码之前所使用的代码)对以下任何一项进行了零验证程序进行必要的函数调用。
即使添加了检查if (content != NULL)
之后,您也无法判断该代码是否已执行,或者您的函数只是返回了0
,因为在失败时没有诊断输出,并且您也没有有意义地使用从readfile
返回(无论成功还是失败-它总是只返回0
)
为每个函数选择一个有意义的返回类型。如果您不需要利用函数的返回值,请将该函数键入void
。
添加有意义的返回类型和值将准确确定程序失败的位置。例如,提供有意义的回报并完全验证您的代码,您可以执行以下操作:
#include <stdio.h>
#define FNAME "file.gif" /* if you need constants, #define one (or more) */
#define MAXC 4000
/* select proper/meaningful return types for your functions */
void printcontents (const unsigned char *storage);
void changecolor (unsigned char *storage);
int readfile (unsigned char *storage, int capacity, char *filename);
int main (void) {
unsigned char data1[MAXC] = {0};
if (!readfile(data1, MAXC, FNAME)) /* validate all necessary calls */
return 1;
printcontents(data1);
changecolor(data1);
printcontents(data1);
return 0;
}
void printcontents (const unsigned char *storage)
{
printf("%X", storage[13]);
}
void changecolor (unsigned char *storage)
{
storage[13] >>= 2;
}
int readfile (unsigned char *storage, int capacity, char *filename)
{
size_t numElements, bytesPer = sizeof(unsigned char);
FILE *content = fopen (filename, "r");
if (!content) {
perror ("fopen-filename");
return 0;
}
if (fseek (content, 0, SEEK_END) == -1) {
perror ("fseek-content");
return 0;
}
if ((long)(numElements = ftell(content)) == -1) {
perror ("ftell-content");
return 0;
}
rewind(content);
if (numElements > capacity * bytesPer)
fprintf (stderr, "warning - file size exceeds read capacity.\n");
if (fread (storage, bytesPer, numElements, content) != numElements) {
fprintf (stderr, "error: less than %zu elements read from %s\n",
numElements, filename);
return 0;
}
fclose (content);
return 1;
}
(注意:请勿在代码中使用魔术数字或硬编码字符串。如果需要常量,{{ 1}}。这使您的代码更易于阅读和维护
脚注:
1。。请勿替换或删除部分原始问题。这样一来,您所做更改之前的所有评论和答案都将变得无关紧要。而是通过在原始内容的底部添加修改来添加到您的问题。这样,所有评论和答案将继续有意义。 (我知道您是新手,所以这一次不讨人喜欢,但是请不要继续做下去)
答案 2 :(得分:0)
如下初始化data1
:
unsigned char data1[4000] = { 0 };