我在main()中调用下面的函数getdata()
。 getdata()
从uart中读取字符并将它们放入数组中。在函数结束时,它通过uart写出数组。
我的问题是,如何让这个函数返回数据?我知道你不能在c中返回数组,你应该声明一个返回指针的函数。
如何使用下面的函数执行此操作,以便我可以在main中写出数据,而不必在getdata()
内执行此操作。
int main(void)
{
getdata();
}
void getdata(void)
{
static uint8_t ndx;
char recChars[6];
char retchar;
ndx = 0;
retchar = getch();
recChars[ndx] = retchar;
ndx++;
if (retchar == '\r'){
recChars[ndx] = '\n';
ndx = 0;
uart_write(UART_D, (uint8_t *)recChars, sizeof(recChars));
}
}
char getch(void) {
uint8_t ch = 0;
chuart_read(UART_D, &ch);
return ((char) ch);
}
答案 0 :(得分:2)
您需要使public int Print(DatabaseConnector dc)
{
try {
// Set up PrintDocument
PrintDocument recordDoc = new PrintDocument();
recordDoc.DocumentName = "PrintTask ID "+id.ToString();
recordDoc.PrintPage += new PrintPageEventHandler(PrintTask.PrintReceiptPage); // Filling in the stuff
// Print Controller
StandardPrintController spc = new StandardPrintController();
recordDoc.PrintController = spc; // This hides popup
// Printer Settings
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = dc.ReadSetting("PrinterName");
recordDoc.PrinterSettings = ps;
recordDoc.Print();
// Clean up
recordDoc.Dispose();
}
catch (Exception exc)
{
((MainForm)Application.OpenForms[0]).msg(exc.Message);
}
return 1; // ignore this
}
private static void PrintReceiptPage(object sender, PrintPageEventArgs e)
{
try {
// Read settings
DatabaseConnector db = new DatabaseConnector();
PrintTask pt = db.ReadTask();
float x = float.Parse(db.ReadSetting("PaperMarginFromLeft"));
float y = float.Parse(db.ReadSetting("PaperMarginFromTop"));
float width = float.Parse(db.ReadSetting("PaperWidth"));
float height = 0F;
string text;
// Set up font
Font drawFont1 = new Font(db.ReadSetting("PrintFont"), Int32.Parse(db.ReadSetting("PrintFontSize")), FontStyle.Regular);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Set format of string.
StringFormat drawFormatLeft = new StringFormat();
drawFormatLeft.Alignment = StringAlignment.Near;
// Draw string to screen.
text = pt.getData();
e.Graphics.DrawString(text, drawFont1, drawBrush, new RectangleF(x, y, width, height), drawFormatLeft);
// calculate text size
SizeF textSize = e.Graphics.MeasureString(text, drawFont1);
y += textSize.Height;
// Set page size - has no effect
e.HasMorePages = false;
float inchHeight = PrintTask.PixelsToInchY(y, e.Graphics);
PaperSize originalPaperSize = e.PageSettings.PaperSize;
PaperSize scaledSize = new PaperSize("Custom", originalPaperSize.Width, (int)Math.Ceiling(inchHeight * 100));
e.PageSettings.PaperSize = scaledSize;
e.PageSettings.PrinterSettings.DefaultPageSettings.PaperSize = scaledSize;
}
catch (Exception exc)
{
((MainForm)Application.OpenForms[0]).msg(exc.Message);
}
}
public static float PixelsToInchX(float n, Graphics graphics)
{
return n * graphics.DpiX / 300;
}
public static float PixelsToInchY(float n, Graphics graphics)
{
return n * graphics.DpiY / 300;
}
指针并使用malloc()
或系列为其分配动态内存。然后,您可以将指针返回给调用者并在调用者中使用它。
像
这样的东西recChars
请记住,在使用结束后,返回的指针需要在调用者中为char * getdata() //change return type
{
static uint8_t ndx;
char * recChars = NULL; // change to pointer
char retchar;
ndx = 0;
if ( (recChars = malloc(6)) == NULL ) return NULL;
retchar = getch();
recChars[ndx] = retchar;
ndx++;
if (retchar == '\r'){
recChars[ndx] = '\n';
ndx = 0;
//uart_write(UART_D, (uint8_t *)recChars, sizeof(recChars));
}
return recChars; //finally return
}
- d,以避免内存泄漏。
答案 1 :(得分:1)
您必须编写一个函数,该函数返回指向char的指针并使用malloc来分配内存。您必须使用malloc,因为数组声明为此
char v[11];
属于自动存储类,这意味着它们具有块作用域,一旦函数返回它们就会被删除,默认情况下它们不会被初始化。如果您有指向该内存块的指针,则可以在程序中的任何位置访问动态内存。您还记得使用free()释放内存以避免内存泄漏。如果你返回一个指向自动数组的指针,你可能会得到一个SIGSEGV,因为你的指针持有的内存位置不再存在。所以你可以这样写:
char *foo(void)
{
char *p = malloc(sizeof(type) * n);
return p;
}
主要
int main(void)
{
char *pointer = foo();
/*Do something*/
free(pointer);
return EXIT_SUCCESS;
}
PS:我为我的英语道歉
答案 2 :(得分:0)
我建议你在main()
函数本身声明一个数组,将arrray作为对getdata函数的引用传递,所以只要getdata()
得到更新,就会反映在{{1}中的数组中}。
注意:顺便说一下你为什么使用sizeof(recChars),这将给出6,但你只能更新2个位置。我也在代码中加入了这个
main()
更新:
可以在main()中调用uart_write()吗?
是的,你可以这样做,但由于int main(void)
{
char recChars[6];
int Rxd_Len = 0;
Rxd_Len = getdata(&recChars); //Pass the address of array
uart_write(UART_D, (uint8_t *)recChars, Rxd_Len );
}
int getdata(char *ptr_recChars)
{
uint8_t ndx; // removed static since its not a required/mandatory
char retchar;
ndx = 0;
retchar = getch();
*(ptr_recChars + ndx) = retchar; //Asign the value to the array address + offset
if (retchar == '\r'){
ndx++;
*(ptr_recChars + ndx) = '\n';
}
return ndx;
}
char getch(void) {
uint8_t ch = 0;
int ret;
ret = uart_read(UART_D, &ch);
return ((char) ch);
}
将使用传输长度,你需要使用另一个变量来跟踪它。
另外,为什么这条线是必要的?它做什么uart_write()
?
ptr_recChars是一个指向数组*(ptr_recChars + ndx) = retchar;
的指针,所以使用这个指针我们可以更新数组recChars[6]
,即使它在recChars[6]
,main()
中声明,*(ptr_recChars + ndx)
1}}是ndx
所以数组的第一个元素被更新,然后你增加0
然后,使用指针变量我们可以指向ndx
新的更新位置(因为*(ptr_recChars + ndx)
现在是新值)
另外,我应该& getdata中的运算符(& recChars);
不,数组名称本身就是一个指针,因此ndx
simplay单独给出recChars[6]
将给出数组的基址,同时注意recChars
和recChars
表示相同。因此,如果您提供&recChars[0]
,则表示&recChars
是一个地址,然后添加recChars
会假定地址的地址会在您的表达式中为您提供无效值。
答案 3 :(得分:0)
如上所述,您可以编写一个返回char *并使用malloc为此表创建一些存储的函数,或者您可以简单地将您的数组声明为静态并返回它。 更明确地说:
char * getdata(void){ static char retChar [6]; ... 返回retChar; }
作品。原因是阵列存储在特殊段中保留。
使用malloc的版本为堆中的数组保留存储空间,这需要您以后释放它:
char * getdata(void){ char * retChar =(char *)malloc(6); ... 返回retChar; }
main(){ char * ptr = getdata(); ... 免费(PTR); }
最后你唯一不能做的就是声明数组并按原样返回它,没有静态声明,也没有malloc ......原因是你的 数组在调用堆栈中分配,因此在返回时可能会丢失 来自getdata。 换句话说,永远不要做: char * getdata(void){ char retChar [6]; ... 返回retChar; }